【问题标题】:Parse element from nested namespaces XML in PHP从 PHP 中的嵌套命名空间 XML 中解析元素
【发布时间】:2013-09-02 10:09:00
【问题描述】:

到目前为止,我所拥有的是下面的代码。 我认为问题出在$bodies = $xml->xpath('domain:cd');, 我不确切知道如何定义路径。

尝试查看一些示例,但无法弄清楚。

XML

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0
epp-1.0.xsd">
<response>
    <result code="1000">
    <msg>Command completed successfully</msg>
    </result>
<resData>
    <domain:chkData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0"
    xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0
    domain-1.0.xsd">
        <domain:cd>
        <domain:name avail="0">domain001.gr</domain:name>
        <domain:reason>In Use.</domain:reason></domain:cd>
    </domain:chkData>
</resData>

PHP 代码

$xml = simplexml_load_string($result, NULL, NULL, 'urn:ietf:params:xml:ns:epp-1.0');
$xml->registerXPathNamespace('domain', 'urn:ietf:params:xml:ns:domain-1.0');

$bodies = $xml->xpath('/resData/domain:chkData');
echo "alitheia";
foreach($bodies as $body){

    $reply = $body->children('domain', TRUE)->cd;

    $nameout =(string)$reply->name;
    echo $nameout;
    echo "alitheia2";

}

“alitheia”回显用于调试以查看我的代码到达的位置。 “Altheia2”从未出现。

在其他人提出此问题时解决它的代码

//i loaded the xml in the p2xml variable using file_get_contents
        $p2xml = new SimpleXmlElement($p2xmlf);
        foreach ($p2xml->response->resData $entry2)
        {
            $namespaces = $entry2->getNameSpaces(true);
            $dc = $entry2->children($namespaces['domain']);
            $nameout = $dc->chkData->name;
            //below is what i used to get the attribute
                            $attrout = $dc->chkData->name->attributes();
            $oxml = $p2xml->asXML();
        }

【问题讨论】:

  • 您的 XML 已损坏,缺少两个结束标记。如果您使用调试输出,最好使用合理的输出,例如var_dump($bodies);。它会帮助您意识到您的 XPath 表达式是错误的/没有返回任何内容。

标签: php xml xpath xml-namespaces


【解决方案1】:

你的代码有两个问题:

  1. 同时注册并使用urn:ietf:params:xml:ns:epp-1.0命名空间:

    $xml->registerXPathNamespace('epp', 'urn:ietf:params:xml:ns:epp-1.0');
    

    并在您的 XPath 表达式中使用它:epp:resData 而不是 resData

  2. 没有&lt;resData/&gt; 根元素。如果您想找到所有这些,请使用//epp:resData/domain:chkData,或提供完整路径:/epp:epp/epp:response/epp:resData/domain:chkData


如果只需要名称,为什么不直接使用 XPath 选择它呢?

$bodies = $xml->xpath('//epp:resData/domain:chkData/domain:cd/domain:name/text()');
// Or even use: '//domain:name/text()'
foreach ($bodies as $body)
  echo $body;

【讨论】:

  • 我不认为 1. 是必要的/有效的,因为在他的示例中,该命名空间被指定为默认的 simplexml_load_string。
  • 好的,现在测试一下,让我不那么懒惰并添加答案,确实没有必要,OP做得很好:stackoverflow.com/a/18598510/367456
【解决方案2】:

你做得很好,唯一不匹配的是元素的路径:

/resData/domain:chkData

这是您的路径,这意味着&lt;resData&gt; 将是根(文档)元素的子元素。但事实并非如此,它是 &lt;response&gt;&gt; 的子元素,它本身就是根元素的子元素:

/response/resData/domain:chkData'
#########

通过这个小小的改动,您的代码就可以正常工作了。

【讨论】:

  • 感谢您的关注和时间。我在上面发布了我的解决方案(编辑了问题)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-23
  • 2019-02-17
  • 2012-06-11
相关资源
最近更新 更多