Parse XML Dom with PHP


Parse XML Dom with PHP

似乎在捕获联系人类型下的字段"admin"时遇到问题

<epp:epp xmlns:epp="urn:ietf:params:xml:ns:epp-1.0">
<epp:response>
<epp:result code="1000">
  <epp:msg>Domain Info Command completed successfully</epp:msg>
</epp:result>
<epp:resData>
  <domain:infData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
    <domain:name>exampledomain.com</domain:name>
    <domain:roid>DOM_1E-PDT</domain:roid>
    <domain:status s="ok"/>
    <domain:registrant>exampleregistrant</domain:registrant>
    <domain:contact type="admin">admincontact</domain:contact>
    <domain:contact type="tech">techcontact</domain:contact>
    <domain:contact type="billing">billingcontact</domain:contact>
    <domain:contact type="reseller">resellercontact</domain:contact>

我尝试的代码是:

$adminid = $doc->getElementsByTagName('admin')->item(0)->nodeValue;

感谢您的帮助。

在节点<domain:contact type="admin">中,"admin"不是节点。它是(节点<domain:contact>的)属性"type"的值。

因此,要检索其节点值,必须查找TagName="domain:contact"且属性为"type=admin"的元素。

Tag Name中的冒号表示NameSpaced节点:不能简单地使用->getElementsByTagName( 'domain:contact' )来搜索它,还必须指定相对的NameSpace URI。您可以在节点祖先之一的属性中找到NamespaceURI,该属性由xmlns:标识,后跟NamespaceTag前缀(在您的情况下为domain)。

在您的XML中,NameSpaceURI位于:

<domain:infData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<!--            └─┬─┘ └─┬──┘  └──────┬────────────────────────┘
 NS declaration prefix  NS prefix    NameSpace URI

要查找NameSpaced元素,可以使用以下语法:

$nodes = $doc->getElementsByTagNameNS( 'urn:ietf:params:xml:ns:domain-1.0', 'contact' );
foreach( $nodes as $node )
{
    if( 'admin' == $node->getAttribute( 'type' ) ) $adminid = $node->nodeValue;
}

否则,您可以使用DOMXPath:

$xpath = new DOMXPath( $doc );
$xpath->registerNameSpace( 'd', 'urn:ietf:params:xml:ns:domain-1.0' );
#                          ┌┘
$nodes = $xpath->query( '//d:contact[@type="admin"]' );
$adminid = $found->item(0)->nodeValue;

正如您所看到的,您可以使用任何别名来引用NameSpace前缀,而不必使用真正的前缀(在上面的示例中,我使用"d"而不是"domain")。

这里有另一个解决方案:

$rawXml = 
<<<XML
    <epp:epp xmlns:epp="urn:ietf:params:xml:ns:epp-1.0">
        <epp:response>
            <epp:result code="1000">
                <epp:msg>Domain Info Command completed successfully</epp:msg>
            </epp:result>
            <epp:resData>
                <domain:infData xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
                    <domain:name>exampledomain.com</domain:name>
                    <domain:roid>DOM_1E-PDT</domain:roid>
                    <domain:status s="ok"/>
                    <domain:registrant>exampleregistrant</domain:registrant>
                    <domain:contact type="admin">admincontact</domain:contact>
                    <domain:contact type="tech">techcontact</domain:contact>
                    <domain:contact type="billing">billingcontact</domain:contact>
                    <domain:contact type="reseller">resellercontact</domain:contact>
                </domain:infData>
            </epp:resData>
        </epp:response>
    </epp:epp>
XML;

 $xmlDoc = new SimpleXMLElement($rawXml);
 $xmlDoc->registerXPathNamespace('domain', 'urn:ietf:params:xml:ns:domain-1.0');
 echo $xmlDoc->xpath('//domain:contact[@type="admin"]')[0];