【问题标题】:PHP: remove node from xml by attributePHP:按属性从xml中删除节点
【发布时间】:2016-11-13 15:49:56
【问题描述】:

假设我有一个这样的 xml:

<products>
    <product id="1">
        <name>aaa</name>
        <producturl>aaa</producturl>
        <bigimage>aaa</bigimage>
        <description>aaa</description>
        <price>aaa</price>
        <categoryid1>aaa</categoryid1>
        <instock>aaa</instock>
    </product>
    <product id="2">
        <name>aaa</name>
        <producturl>aaa</producturl>
        <bigimage>aaa</bigimage>
        <description>aaa</description>
        <price>aaa</price>
        <categoryid1>aaa</categoryid1>
        <instock>aaa</instock>
    </product>
</products>

如果该属性在数组中,我需要根据 id 属性删除某些节点。

我尝试了不同的方法,但输出的xml始终是原始的!

到目前为止我的代码:

<?php header("Content-type: text/xml");
$url="http://www.aaa.it/aaa.xml";
$url=file_get_contents($url);
$array=array("1","4","5");
$doc=new SimpleXMLElement($url);
foreach($doc->product as $product){
    if(!in_array($product['id'],$array)){
        $dom=dom_import_simplexml($product);
        $dom->parentNode->removeChild($dom);
        // unset($doc->product->$product);
    }
}
echo $doc->asXml(); ?>

非常感谢大家。

【问题讨论】:

    标签: php xml nodes unset


    【解决方案1】:

    考虑部分 XPath 和 XSLT 解决方案,它们都是 Extensible Stylesheet Family 中的兄弟姐妹。 XPath 首先用于检索所有当前的产品 id,然后将其与当前的 id 数组进行比较以继续使用array_diff。然后迭代构建 XSLT 以根据这些不匹配的 id 删除节点。在 XSLT 中删除节点只需要一个空模板匹配。

    // Load the XML source
    header("Content-type: text/xml");
    $url="http://www.aaa.it/aaa.xml";
    $url=file_get_contents($url);
    $doc=new SimpleXMLElement($url);
    
    // Retrieve all XML product ids with XPath
    $xpath = $doc->xpath("//product/@id");
    $xmlids = [];
    foreach($xpath as $item => $value){ $xmlids[] = (string)$value; }
    
    // Compare difference with $array
    $array = array("1","4","5");
    $removeids = array_diff($xmlids, $array);
    
    // Dynamically build XSLT string for each resulting id
    foreach($removeids as $id){        
      $xslstr='<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
                 <xsl:output version="1.0" encoding="UTF-8" indent="yes" />
                 <xsl:strip-space elements="*"/>
    
                  <xsl:template match="@*|node()">
                     <xsl:copy>
                       <xsl:apply-templates select="@*|node()"/>
                     </xsl:copy>
                  </xsl:template>
    
                  <xsl:template match="product[@id=\''.$id.'\']"/>
    
               </xsl:transform>';                    
      $xsl = new SimpleXMLElement($xslstr);
    
      // Configure the transformer and run
      $proc = new XSLTProcessor;
      $proc->importStyleSheet($xsl);
      $newXML = $proc->transformToXML($doc);
    
      // Adjust $doc object with each loop
      $doc = new SimpleXMLElement($newXML);
    }
    
    // Echo Output    
    echo $doc->asXML();   
    

    【讨论】:

    • 我没有那个扩展(XSLTProcessor)
    • 您可以在 .ini 文件中启用extension
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多