2

I am creating a XML from a string (This string is a value of another XML).

I tried simplexml_load_string to create.

My Scenerio:

My UI is in php and I am sending Excel sheet data through PHPExcel to my project's services part. It returns:

<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>
   <root>
     <searcheddata>
         {Account0={AccountName=1, AddressLine2=0.0, Country=0.0, CellPhone=0.0, City=0.0, WorkPhone=0.0, Other=0.0, HomePhone=0.0, Email=0.0, AddressLine1=0.0, State=0.0, Zip=0.0, AlternateEmail=0.0},  City1={City=1, AddressLine2=0.0, Country=0.0, CellPhone=0.0, WorkPhone=0.0, Other=0.0, HomePhone=0.0, Email=0.0, AddressLine1=0.0, State=0.0, Zip=0.0, AlternateEmail=0.0},  State2={State=1, AddressLine2=0.0, Country=0.0, CellPhone=0.0, City=0.0, WorkPhone=0.0, Other=0.0, HomePhone=0.0, Email=0.0, AddressLine1=0.0, Zip=0.0, AlternateEmail=0.0},  Country3={Country=1, AddressLine2=0.0, CellPhone=0.0, City=0.0, WorkPhone=0.0, Other=0.0, HomePhone=0.0, Email=0.0, AddressLine1=0.0, State=0.0, Zip=0.0, AlternateEmail=0.0}}
        </searcheddata>
    </root>

Now I trying to create XML from the value of <searcheddata>.

Atlast I need a XML as:

<xml>
     <root>
        <Account0>
            <AccountName>1</AccountName>
            <AddressLine2>0.0</AddressLine2>
            <Country>0.0</Country>
            <CellPhone>0.0</CellPhone>
            <City>0.0</City>
            <WorkPhone>0.0</WorkPhone>
            <Other>0.0</Other>
            <HomePhone>0.0</HomePhone>
            <AddressLine1>0.0</AddressLine1>
            <State>0.0</State>
            <Zip>0.0</Zip>
            <AlternateEmail>0.0</AlternateEmail>
        </Account0>
        <City1>
            <City>1</City>
            <AddressLine2>0.0</AddressLine2>
            <Country>0.0</Country>
            <CellPhone>0.0</CellPhone>
            <WorkPhone>0.0</WorkPhone>
            <Other>0.0</Other>
            <HomePhone>0.0</HomePhone>
            <AddressLine1>0.0</AddressLine1>
            <State>0.0</State>
            <Zip>0.0</Zip>
            <AlternateEmail>0.0</AlternateEmail>
        </City1>
     </root>
 </xml>

What I tried:

<?php

$str = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><root><searcheddata>{Account0={AccountName=1, AddressLine2=0.0, Country=0.0, CellPhone=0.0, City=0.0, WorkPhone=0.0, Other=0.0, HomePhone=0.0, Email=0.0, AddressLine1=0.0, State=0.0, Zip=0.0, AlternateEmail=0.0},  City1={City=1, AddressLine2=0.0, Country=0.0, CellPhone=0.0, WorkPhone=0.0, Other=0.0, HomePhone=0.0, Email=0.0, AddressLine1=0.0, State=0.0, Zip=0.0, AlternateEmail=0.0},  State2={State=1, AddressLine2=0.0, Country=0.0, CellPhone=0.0, City=0.0, WorkPhone=0.0, Other=0.0, HomePhone=0.0, Email=0.0, AddressLine1=0.0, Zip=0.0, AlternateEmail=0.0},  Country3={Country=1, AddressLine2=0.0, CellPhone=0.0, City=0.0, WorkPhone=0.0, Other=0.0, HomePhone=0.0, Email=0.0, AddressLine1=0.0, State=0.0, Zip=0.0, AlternateEmail=0.0}}</searcheddata></root>";

$a = array();
$name = array();
$values = array();
$mainArray = array();
$xml = simplexml_load_string($str);
$s3 = $xml->searcheddata;
$pieces = (explode("},", $s3));
$pieces[0] = substr($pieces[0], 1);
$length = sizeof($pieces);
$pieces[$length - 1] = substr($pieces[$length - 1], 0, -2);
foreach ($pieces as $value) {
    $morePiece = (explode("={", $value));
    for ($i = 0; $i < sizeof($morePiece); $i = $i + 2) {
        $lastPiece = explode(", ", $morePiece[$i]);
        for ($j = 0; $j < sizeof($lastPiece); $j++) {
            array_push($a, $lastPiece[0]);
        }
    }
    for ($i = 1; $i < sizeof($morePiece); $i = $i + 2) {
        $lastPiece2 = explode(", ", $morePiece[$i]);
        for ($j = 0; $j < sizeof($lastPiece2); $j++) {
            $finalPiece2 = explode("=", $lastPiece2[$j]);
            for ($k = 0; $k < sizeof($finalPiece2); $k++) {
                if ($k % 2 == 0) {
                    array_push($name, $finalPiece2[$k]);
                } else {
                    array_push($values, $finalPiece2[$k]);
                }
            }
        }
    }
}
echo sizeof($pieces)."<br>";
print_r($a);
echo '<br><br>';
print_r($name);
echo '<br><br>';
print_r($values);
echo '<br><br>';
?>

I was trying to put all my key and value in respective array and then to create a XML using simplexml-load-string.

Suggestions are welcome.

1 Answer 1

2

Trying hard to avoid writing a full parser, the following combines some regular expressions and conversions from different formats (string, JSON, array, SimpleXML and DOMDocument) to achieve the desired result.

I must admin it is a tiny bit hackish though - one current limitation, for example, is that values are required to be numeric as per your example (e.g. 123 or 123.45) - but may be enough in you case.

$source =<<<XML
<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>
<root>
    <searcheddata>
        {Account0={AccountName=1, AddressLine2=0.0, Country=0.0, CellPhone=0.0, City=0.0, WorkPhone=0.0, Other=0.0, HomePhone=0.0, Email=0.0, AddressLine1=0.0, State=0.0, Zip=0.0, AlternateEmail=0.0},  City1={City=1, AddressLine2=0.0, Country=0.0, CellPhone=0.0, WorkPhone=0.0, Other=0.0, HomePhone=0.0, Email=0.0, AddressLine1=0.0, State=0.0, Zip=0.0, AlternateEmail=0.0},  State2={State=1, AddressLine2=0.0, Country=0.0, CellPhone=0.0, City=0.0, WorkPhone=0.0, Other=0.0, HomePhone=0.0, Email=0.0, AddressLine1=0.0, Zip=0.0, AlternateEmail=0.0},  Country3={Country=1, AddressLine2=0.0, CellPhone=0.0, City=0.0, WorkPhone=0.0, Other=0.0, HomePhone=0.0, Email=0.0, AddressLine1=0.0, State=0.0, Zip=0.0, AlternateEmail=0.0}}
    </searcheddata>
</root>
XML;

// Get rid of backslashes
$source = stripslashes($source);

// Create XML object, grab the data and remove whitespace
$xml  = new SimpleXMLElement($source);
$data = (string)$xml->searcheddata;
$data = preg_replace('/\s/', '', $data);

// Turn data into JSON:
// {foo={bar=1, baz=2.34}} => {"foo":{"bar":"1","baz":"2.34"}}
$data = preg_replace('/(\w+)=([\d\.]+)/', '"\1":"\2"', $data);
$data = preg_replace('/(\w+)=/',          '"\1":',     $data);

// Turn JSON into associative array
$decodedJson = json_decode($data, true);

// Function for adding array elements as XML child elements to XML element
function addElements(SimpleXMLElement $element, $a)
{
    foreach ($a as $key => $value) {
        if (is_array($value)) {
            $child = $element->addChild($key);
            addElements($child, $value);
        } else
            $element->addChild($key, $value);
    }
}

// Turn array into another Simple XML element and create <xml> and <root> tags
$simpleXml = new SimpleXMLElement('<xml/>');
$root      = $simpleXml->addChild('root');
addElements($root, $decodedJson);

// Pretty output by converting SimpleXML object to DOMElement
$dom = dom_import_simplexml($simpleXml)->ownerDocument;
$dom->formatOutput = true;
echo $dom->saveXML();

Output:

<?xml version="1.0"?>
<xml>
  <root>
    <Account0>
      <AccountName>1</AccountName>
      <AddressLine2>0.0</AddressLine2>
      <Country>0.0</Country>
      <CellPhone>0.0</CellPhone>
      <City>0.0</City>
      <WorkPhone>0.0</WorkPhone>
      <Other>0.0</Other>
      <HomePhone>0.0</HomePhone>
      <Email>0.0</Email>
      <AddressLine1>0.0</AddressLine1>
      <State>0.0</State>
      <Zip>0.0</Zip>
      <AlternateEmail>0.0</AlternateEmail>
    </Account0>
    <City1>
      <City>1</City>
      <AddressLine2>0.0</AddressLine2>
      <Country>0.0</Country>
      <CellPhone>0.0</CellPhone>
      <WorkPhone>0.0</WorkPhone>
      <Other>0.0</Other>
      <HomePhone>0.0</HomePhone>
      <Email>0.0</Email>
      <AddressLine1>0.0</AddressLine1>
      <State>0.0</State>
      <Zip>0.0</Zip>
      <AlternateEmail>0.0</AlternateEmail>
    </City1>
    ...
  </root>
</xml>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.