在PHP中替换和修改XML节点

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.

dou44364983
dou44364983 对不起,这是一个错字。我已经纠正了这一点。
大约 7 年之前 回复
doujiao1984
doujiao1984 您的XML中存在标记不匹配。你确定XML是正确的吗?
大约 7 年之前 回复

3个回答

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;
?> 

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.

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());
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问
相关内容推荐