0

Here's a sample XML structure:

<Products>
    <Product>
        <Id>1</Id>
        <Name>Product 1</Name>
        <Category>MEN</Category>
        <Category>Women</Category>
    <Product>
    <Product>
        <Id>2</Id>
        <Name>Product 2</Name>
        <Category>MEN2</Category>
        <Category>Women2</Category>
    <Product>
</Products>

And I want the file like this:

<Products>
    <Product>
        <Id>1</Id>
        <Name>Product 1</Name>
        <CategoryName>MEN:Women</CategoryName>
    <Product>
    <Product>
        <Id>2</Id>
        <Name>Product 2</Name>
        <CategoryName>MEN:Women</CategoryName>
    <Product>
</Products>

So basically it will search through the nodes in products. If it finds "Category", it will change the name to "CategoryName" and concatenate all the sub-sequent category node values into a single one separated by semicolon.

So I have wrote this small PHP, but not sure how to get this to work.

<?php
    $xmlFile = "test.xml" //assume the contents are in the file
    $xml = simplexml_load_file($xmlFile);

    foreach($xml as $item)
    {
        $name = $item->Product;
        if($name->count()) //check if its a "product" node
        {
            foreach($item as $i)
            {
                $category = $i->Category;
            }
        }
     }
?> 

Can someone point me to the right direction? I haven't much worked with XML.

2
  • There's a tag mismatch in your XML. Are you sure the XML is correct? Commented Jul 26, 2013 at 5:47
  • Sorry that was a typo. I've corrected that. Commented Jul 26, 2013 at 5:51

3 Answers 3

1

Please Use this

<?php
    $xmlFile = "test.xml"; //assume the contents are in the file
    $xml = simplexml_load_file($xmlFile);   
    $table = '<Products>';
    foreach($xml as $item)
    {    
      $table .= '<Product>';
      $table .= '<Id>'.$item->Id.'</Id>';
      $table .= '<Name>'.$item->Name.'</Name>';
      $table .= '<Category>';
      $i = 0;
      foreach($item->Category as $cat)
        {
         if($i>0){
         $table .= ':'; 
         }   
         $table .= $cat;
         $i++;
        }
       $table .= '</Category>';
       $table .= '</Product>'; 
     }
      $table .= '</Products>';
      echo $table;
?> 
Sign up to request clarification or add additional context in comments.

Comments

0

Try this:

$xml = '<Products>
    <Product>
        <Id>1</Id>
        <Name>Product 1</Name>
        <Category>MEN</Category>
        <Category>Women</Category>
    </Product>
    <Product>
        <Id>2</Id>
        <Name>Product 2</Name>
        <Category>MEN2</Category>
        <Category>Women2</Category>
    </Product>
</Products>';

$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML( $xml, LIBXML_NOBLANKS );

$xpath = new DOMXPath( $dom );

$ProductNode = $xpath->query( "//Product" );

if( $ProductNode->length ) {
    foreach ( $ProductNode as $node ) {
        $category = $node->getElementsByTagName( 'Category' );
        $str = '';
            // store a reference to the nodes,
            // so that they can be deleted later
        $del = array();

        foreach ( $category as $p ) {
            $str .= $p->nodeValue . ':';
            $del[] = $p;
        }

        $str = trim( $str, ':' );

        $child = $dom->createElement( 'CategoryName', $str );
        $node->appendChild( $child );

        foreach ( $del as $p ) {
            $p->parentNode->removeChild( $p );
        }
    }
}

header('content-type: text/xml');
echo $dom->saveXML();

Hope it helps.

Comments

0

Use DomDocument, if you want to modify XML while traversing it:

$xml_obj = new DOMDocument();
$xml_obj->loadXML($xml_string, LIBXML_NOBLANKS );
$xml_obj->preserveWhiteSpace = false;
$xml_obj->formatOutput = true;
$products = $xml_obj->getElementsByTagName('Product');
foreach ($products as $product) {
    $cats = array();
    $categories = $product->getElementsByTagName('Category');
    $tot = $categories->length;
    $to_delete = array();
    for($i = 0; $i < $tot;$i++) {
        $cat = $categories->item($i);
        $cats[] = $cat->textContent;
        $to_delete[]  = $cat;

    }
    foreach ($to_delete as $delete_node) {
        $product->removeChild($delete_node);
    }
    $product->appendChild($xml_obj->createElement('CategoryName', implode(":", $cats)));
}

print ($xml_obj->saveXML());

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.