Reputation: 644
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.
Upvotes: 2
Views: 76
Reputation: 3701
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>
Upvotes: 2