1

I have an XML with attribute like this:

<products>
<product ProductName="One" ProductCategory="Software::Utilities::Email">
<product ProductName="Two" ProductCategory="Software::Video::Editing">
<product ProductName="Three" ProductCategory="Software::Audio::Converter">
</products>

And how can I explode the "ProductCategory" attribute and separated it like this:

<products>
<product ProductName="One" ProductCategory="Software">
<product ProductName="One" ProductCategory="Utilities">
<product ProductName="One" ProductCategory="Email">
<product ProductName="Two" ProductCategory="Software">
<product ProductName="Two" ProductCategory="Video">
<product ProductName="Two" ProductCategory="Editing">
<product ProductName="Three" ProductCategory="Software">
<product ProductName="Three" ProductCategory="Audio">
<product ProductName="Three" ProductCategory="Converter">
</products>
Cameron Skinner
  • 51,692
  • 2
  • 65
  • 86

2 Answers2

0

An Example for you

<?php
$string = <<<XML
<products>
    <product ProductName="One" ProductCategory="Software::Utilities::Email"></product>
    <product ProductName="Two" ProductCategory="Software::Video::Editing"></product>
    <product ProductName="Three" ProductCategory="Software::Audio::Converter"></product>
</products>
XML;

$xml = simplexml_load_string($string);
$obj = json_decode(json_encode($xml), true);

$new_xml = '<products>';

foreach($obj['product'] as $val){
    $name = $val['@attributes']['ProductName'];
    $pro = explode('::', $val['@attributes']['ProductCategory']);
    foreach($pro as $k=>$v){
        $new_xml .= '<product ProductName="'.$name.'" ProductCategory="'.$v.'"></product>';
    }
}
$new_xml .= '</products>';
$file = fopen("test.xml","w");
fwrite($file, $new_xml);
fclose($file);
?>
MH2K9
  • 11,951
  • 7
  • 32
  • 49
  • Here is not need to convert the XML into an array structure, you could iterate the SimpleXML just fine. You missed the escaping for the values you put into XML. – ThW Oct 24 '14 at 09:26
0

You example XML is not valid XML. Make sure to close the product element nodes.

Load the source document into a DOM, create a new target DOM. Import the document element into the target (without child). This will create a copy of that node.

Iterate the product nodes and read the ProductCategory attribute, explode it into an array. Iterate the array an copy the node into the target document (for each value), change the attribute to the value.

$source = new DOMDocument();
$source->loadXml($xml);
$xpath = new DOMXPath($source);

$target = new DOMDocument();
$target->formatOutput = true;
$root = $target->appendChild($target->importNode($source->documentElement));

foreach ($xpath->evaluate('/products/product') as $node) {
  $list = explode('::', $node->getAttribute('ProductCategory'));
  foreach ($list as $value) {
    $newNode = $root->appendChild($target->importNode($node));
    $newNode->setAttribute('ProductCategory', $value);
  }
}

echo $target->saveXml();

Demo: https://eval.in/209729

ThW
  • 19,120
  • 3
  • 22
  • 44