【问题标题】:SimpleXML xpath to element with certain attribute value?SimpleXML xpath 到具有特定属性值的元素?
【发布时间】:2015-02-24 23:15:27
【问题描述】:

我有一些这样的 XML:

<item>
    <custom-attributes>
      <custom-attribute attribute-id="taco">false</custom-attribute>
      <custom-attribute attribute-id="htmlContent" xml:lang="en-US">testValue</custom-attribute>
      <custom-attribute attribute-id="htmlContent" xml:lang="default">testing123</custom-attribute>
  </custom-attribute>
</item>

我如何使用 xpath 找到 custom-attribute 元素而不是 taco 的属性 ID?

我如何使用 xpath 来查找 custom-attribute 元素而不是 htmlContent 的属性 ID?在这种情况下有 2 个。这些也有命名空间。我不确定这是否重要。

我尝试过这样的事情:

var_dump($xml->xpath("custom-attribute[@attribute-id='taco']"));

但这不起作用。我可以遍历custom-attribute 元素并查找我需要的内容,但是通过xpath 简单地选择它会容易得多。

我在这里错过了什么?

【问题讨论】:

    标签: php xml xpath xml-parsing simplexml


    【解决方案1】:

    在 xpath 的开头添加双斜杠:

    $source = <<<X
    <item>
        <custom-attributes>
          <custom-attribute attribute-id="taco">false</custom-attribute>
          <custom-attribute attribute-id="htmlContent" xml:lang="en-US">testValue</custom-attribute>
          <custom-attribute attribute-id="htmlContent" xml:lang="default">testing123</custom-attribute>
      </custom-attributes>
    </item>
    X;
    
    $xml = new SimpleXMLElement($source);
    
    $taco             = $xml->xpath("//custom-attribute[@attribute-id='taco']")[0];
    $htmlContentArray = $xml->xpath("//custom-attribute[@attribute-id='htmlContent']");
    
    echo "taco       : ", $taco, PHP_EOL;
    echo "htmlContent: ", implode(', ', $htmlContentArray), PHP_EOL;
    

    输出:

    taco       : false
    htmlContent: testValue, testing123
    

    更新

    对于您在 cmets 中的问题,关于在 item 节点内进行搜索;您可以使用.// 从当前节点开始搜索。

    // Find an item, then do an xpath on the result of that
    // to find the custom attribute element.
    // <items> tag added as <item> would otherwise be the root element,
    // which would make the example quite pointless.
    $source = <<<X
    <items>
        <item>
            <custom-attributes>
                <custom-attribute attribute-id="taco">false</custom-attribute>
                <custom-attribute attribute-id="htmlContent" xml:lang="en-US">testValue</custom-attribute>
                <custom-attribute attribute-id="htmlContent" xml:lang="default">testing123</custom-attribute>
            </custom-attributes>
        </item>
        <item>
            <custom-attributes>
                <custom-attribute attribute-id="taco">true</custom-attribute>
                <custom-attribute attribute-id="htmlContent" xml:lang="en-US">item 2 testValue</custom-attribute>
                <custom-attribute attribute-id="htmlContent" xml:lang="default">item 2 testing456</custom-attribute>
              </custom-attributes>
        </item>
    </items>
    X;
    
    $xml = new SimpleXMLElement($source);
    
    $item             = $xml->item[1]; // Get second item
    $taco             = $item->xpath(".//custom-attribute[@attribute-id='taco']");
    $htmlContentArray = $item->xpath(".//custom-attribute[@attribute-id='htmlContent']");
    
    echo "taco from second item: ", $taco[0], PHP_EOL;
    echo "html from second item: ", implode(', ', $htmlContentArray), PHP_EOL;
    

    输出:

    taco from second item: true
    html from second item: item 2 testValue, item 2 testing456
    

    【讨论】:

    • 所以 xpath 返回一个数组,而不是 SimpleXMLElement?
    • 实际上 XPath 表达式根据表达式返回节点列表或标量,SimpleXML 将其转换为 SimpleXMLElement 对象数组。
    • 嗯。是否可以使用 xpath 查找item,然后对其结果执行 xpath 以查找自定义属性元素?我可能在我的问题中简化了我的 XML 有点太多了。
    • 当然,请参阅更新的答案。您可能还想查看有关 XPath 语法的 w3schools.com/xpath/xpath_syntax.asp 页面。
    • 感谢您的详尽回答。我现在正在尝试使用已注册的命名空间来执行此操作:xpath("//ns:item[@item-id='item34-test']/custom-attributes/custom-attribute[@attribute-id='taco']"); 但它只是不起作用。我认为命名空间引起了问题。我可能会发布另一个更具体的问题。再次感谢。
    猜你喜欢
    • 2010-11-02
    • 1970-01-01
    • 2012-11-30
    • 1970-01-01
    • 2016-02-13
    • 2016-06-25
    • 1970-01-01
    • 2022-01-03
    • 2011-08-03
    相关资源
    最近更新 更多