xPath找不到*

Hub*_*bro 3 php xml xpath simplexml

这开始让我真的很糟糕.我有这个XML代码:

更新了正确的命名空间

<?xml version="1.0" encoding="utf-8"?>

<Infringement xsi:schemaLocation="http://www.movielabs.com/ACNS http://www.movielabs.com/ACNS/ACNS2v1.xsd" xmlns="http://www.movielabs.com/ACNS" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Case>
    <ID>...</ID>
    <Status>Open</Status>
  </Case>
  <Complainant>
    <Entity>...</Entity>
    <Contact>...</Contact>
    <Address>...</Address>
    <Phone>...</Phone>
    <Email>...</Email>
  </Complainant>
  <Service_Provider>
    <Entity>...</Entity>
    <Address></Address>
    <Email>...</Email>
  </Service_Provider>
  <Source>
    <TimeStamp>...</TimeStamp>
    <IP_Address>...</IP_Address>
    <Port>...</Port>
    <DNS_Name></DNS_Name>
    <Type>...</Type>
    <UserName></UserName>
    <Number_Files>1</Number_Files>
    <Deja_Vu>No</Deja_Vu>
  </Source>
  <Content>
    <Item>
      <TimeStamp>...</TimeStamp>
      <Title>...</Title>
      <FileName>...</FileName>
      <FileSize>...</FileSize>
      <URL></URL>
    </Item>
  </Content>
</Infringement>
Run Code Online (Sandbox Code Playgroud)

这个PHP代码:

<?php 
    $data = urldecode($_POST["xml"]);
    $newXML = simplexml_load_string($data);

    var_dump($newXML->xpath("//ID"));
?>
Run Code Online (Sandbox Code Playgroud)

我只丢弃了$ newXML并获得了大量数据,但是我运行的唯一xPath返回了任何东西,但是一个空数组是"*"

是不是"// ID"应该找到文档中的所有ID节点?为什么不工作?

谢谢

jas*_*sso 9

您的XML文档的根元素似乎具有URI" http://www.movi​​elabs.com/ACNS "的默认命名空间.这意味着文档中的所有元素都属于该命名空间.问题是所有没有名称空间前缀的XPath表达式都在搜索不属于任何名称空间的元素.要从某个名称空间搜索元素(或属性...),您需要将名称空间URI注册到某个前缀,然后在XPath表达式中使用此前缀.

对于PHP的simpleXML,它就是这样做的

$newXML = simplexml_load_string($data);
$newXML->registerXPathNamespace('prefix', 'http://www.movielabs.com/ACNS');
var_dump($newXML->xpath("//prefix:ID"));
Run Code Online (Sandbox Code Playgroud)

prefix实际上可以是任何文本,但命名空间URI必须与XML文档中使用的完全匹配.


Lar*_*rsH 7

我只丢弃了$ newXML并获得了大量数据,但是我运行的唯一xPath返回了任何东西,但是一个空数组是"*"

那是什么回来了var_dump($newXML->xpath("*"));<Infringement>

如果问题是名称空间,请尝试以下方法:

var_dump($newXML->xpath("//*[local-name() = 'ID']"));
Run Code Online (Sandbox Code Playgroud)

这将匹配文档中名称为"ID"的任何元素,而不管命名空间如何.

如果我用"ns"替换所有"xmlns",我的东西是有效的

等等,什么?您确定在文档中向我们展示了所有与xmlns相关的属性吗?

更新: 编辑该问题以显示XML确实具有默认名称空间声明.这解释了原始问题:您的XPath表达式选择了没有名称空间的ID元素,但是文档中的元素位于movielabs ACNS名称空间中,这要归功于默认的名称空间声明.

xmlns="http://www.movielabs.com/ACNS"元素上的声明意味着"此元素和所有没有名称空间前缀(如ID)的后代都在名称空间URI" http://www.movi​​elabs.com/ACNS "所代表的名称空间中." (除非介入的后代具有不同的默认命名空间声明,否则会影响此声明.)

因此,使用local-name()上面的答案忽略名称空间,或使用jasso的技术指定movielabs ACNS并按预期使用它.