【问题标题】:PHP - Namespace Shift in Child Node in SimpleXML TroubleshootingPHP - SimpleXML 故障排除中子节点中的命名空间转移
【发布时间】:2018-07-06 01:22:31
【问题描述】:

我正在使用 SimpleXML 和 XPath 来尝试获取子节点 ('IndexEntry) 属性 ('indexKey') 的值。节点的命名空间,我已经在另一个节点('Record')上成功测试过。 由于某种原因,该节点的属性('indexKey')没有返回。我尝试使用 children 方法访问节点,同时指定其命名空间。

PHP 代码

<?php
$url = "test_bb.xml";


$xml = simplexml_load_file($url);

$xml->registerXPathNamespace('a','http://www.digitalmeasures.com/schema/data');
$xml->registerXPathNamespace('dmd','http://www.digitalmeasures.com/schema/data-metadata');

$xml_report_abbrev_bb = $xml->xpath('//a:Record[@username="john-smith"]');

if($xml_report_abbrev_bb){
    echo '<br>CONTYPE is...'.$xml_report_abbrev_bb[0]->INTELLCONT->CONTYPE;
    echo '<br>termId is...'.$xml_report_abbrev_bb[0]['termId'].'<br>';
    echo '<br>surveyId is...'.$xml_report_abbrev_bb[0]->attributes('dmd',true)['surveyId'].'<br>';

//below - I've tried different methods of accessing the IndexEntry node...
    $dmd_fields = $xml_report_abbrev_bb[0]->children('dmd',true);
    echo '<br>dmd:IndexEntry is...'.$dmd_fields->IndexEntry['indexKey'].'<br>';

    echo '<br>dmd:IndexEntry is...'.$xml_report_abbrev_bb[0]->children('dmd',true)->IndexEntry['indexKey'].'<br>';

    //echo '<br>dmd:IndexEntry is...'.$xml_report_abbrev_bb[0]->IndexEntry('dmd',true)['indexKey'].'<br>';

    //echo '<br>dmd:IndexEntry is...'.$xml_report_abbrev_bb[0]->xpath('/dmd:indexEntry[@indexKey]')[0].'<br>';


} else {
    echo 'XPath query failed b';  
}

?>

XML ('test_bb.xml')

<?xml version="1.0" encoding="UTF-8"?>
<Data xmlns="http://www.digitalmeasures.com/schema/data" xmlns:dmd="http://www.digitalmeasures.com/schema/data-metadata" dmd:date="2012-01-03">
    <Record userId="148" username="john-smith" termId="4" dmd:surveyId="12">
        <dmd:IndexEntry indexKey="D" entryKey="Dylan" text="Dylan"/>
        <INTELLCONT id="14" dmd:originalSource="54TEX" dmd:lastModified="2017-04-18T10:54:29" dmd:startDate="2011-01-01" dmd:endDate="2011-12-31">
            <CONTYPE>Sales Tools</CONTYPE>
            <CONTYPEOTHER>Sales History</CONTYPEOTHER>
            </INTELLCONT>
    </Record>
</Data>

【问题讨论】:

    标签: php xml xpath simplexml xml-namespaces


    【解决方案1】:

    在一行

    $dmd_fields = $xml_report_abbrev_bb[0]->children('dmd', true);
    

    这意味着$dmd_fields 将是一个节点列表,即使列表中只有一个节点 - 所以使用$dmd_fields[0] 来引用&lt;dmd:IndexEntry&gt; 元素。由于这是 IndexEntry 元素,只需使用此元素和该元素的列表关闭属性即可...

    echo '<br>dmd:IndexEntry is...'.$dmd_fields[0]->attributes()['indexKey'].'<br>';
    

    【讨论】:

    • 按名称从节点列表中引用一个项目应该可以正常工作; SimpleXML 被设计为对此非常宽容。
    • 谢谢 - 我只是倾向于不喜欢依赖“应该”发生的事情。我对 PHP 和某些框架的最大问题之一是很多事情往往是通过“魔术”发生的。
    【解决方案2】:

    虽然IndexEntry 元素位于http://www.digitalmeasures.com/schema/data-metadata 命名空间中,由本地前缀dmd: 表示,但它的属性没有前缀

    <dmd:IndexEntry indexKey="D" entryKey="Dylan" text="Dylan"/>
    
    本文档中的

    无前缀元素 位于http://www.digitalmeasures.com/schema/data 命名空间中,如根节点上的xmlns= 属性中所指定。

    但是正如discussed on this question,XML 命名空间规范说属性永远不会在默认命名空间中。这使得它们,特别是,根本没有命名空间,所以要使用 SimpleXML 访问它们,你必须选择其 URI 是空字符串的命名空间:

    $dmd_fields->IndexEntry->attributes('')->indexKey;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-30
      • 2012-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-21
      • 1970-01-01
      • 2015-05-14
      相关资源
      最近更新 更多