PHP和XML按属性值读取元素


PHP & XML Read element by attribute value

$xml = '<?xml version="1.0"?>
<entries>
    <response>
        <category>client</category>
        <action>Greeting</action>
        <code>1000</code> 
        <msg>Your Connection with API Server is Successful</msg> 
        <resData> 
            <data name="svDate">2010-10-10 02:27:14</data> 
        </resData>
    </response>
    <response>
        <category>client</category>
        <action>Login</action>
        <code>1000</code>
        <msg>Command completed successfully</msg>
        <value>L116:no value</value>
    </response>
    <response>
        <category>domain</category>
        <action>InfoDomain</action>
        <code>1000</code>
        <msg>Command completed successfully</msg>
        <value>L125:no value</value>
        <resData>
            <data name="domain">google.com</data>
            <data name="crDate">2004-12-16</data>
            <data name="exDate">2013-12-16</data>
        </resData>
    </response>
</entries>';
$xml = simplexml_load_string($xml);
$domain = $xml->response[2]->resData[0]->data[0];
$crdate = $xml->response[2]->resData[0]->data[1];
$exdate = $xml->response[2]->resData[0]->data[2];

使用上面的代码,我可以得到值。但是我怎么能得到属性值的值?

例如,我想获得这样的值:

$domain = $xml->response[2]->resData[0]->data["domain"];
$crdate = $xml->response[2]->resData[0]->data["crdate"];
$exdate = $xml->response[2]->resData[0]->data["exdate"];

还有一个问题

如果我有两个具有相同名称的元素?例如,我想解析dns。我怎么能做到呢?

xml代码如下:

    <?xml version="1.0"?>
<entries>
    <response>
        <category>client</category>
        <action>Greeting</action>
        <code>1000</code> 
        <msg>Your Connection with API Server is Successful</msg> 
        <resData> 
            <data name="svDate">2010-10-10 02:27:14</data> 
        </resData>
    </response>
    <response>
        <category>client</category>
        <action>Login</action>
        <code>1000</code>
        <msg>Command completed successfully</msg>
        <value>L116:no value</value>
    </response>
    <response>
        <category>domain</category>
        <action>InfoDomain</action>
        <code>1000</code>
        <msg>Command completed successfully</msg>
        <value>L125:no value</value>
        <resData>
            <data name="domain">google.com</data>
            <data name="crDate">2004-12-16</data>
            <data name="exDate">2013-12-16</data>
            <data name="dns">ns1.google.com</data>
          <data name="dns">ns2.google.com</data>
        </resData>
    </response>
</entries>

可以看到ns1和ns2具有相同的名称。name = " dns"。我如何在不同的变量中解析每一个?

谢谢!

element["attribute"]语法中,attributeelement上的属性名。它不是属于某个元素的某个随机选择的属性的值。

下面的示例创建了一个数组,其中包含name属性值的data元素到文本值的映射。

$data = array();
foreach ($xml->response[2]->resData->data as $d) {
    $data[strtolower($d['name'])] = (string) $d;
}
// Now you can access the values via $data['domain'], $data['crdate'], etc.

Nick,你的代码期望XML结构如下:

<resData>
    <data domain="google.com" crdate="2004-12-16" exdate="2013-12-16" />
</resData>

由于问题更改而编辑

在很大程度上收回了我自己的话,由于问题的变化,XPath方法会更合适(难道您不喜欢这样做的OPs吗?)。

您可以使用基本的XPath表达式轻松地获得name="dns"元素的数组。

$xml = simplexml_load_string($xml);
$dns = $xml->xpath('response[category="domain"]/resData/data[@name="dns"]');

您可以使用XPath对XML进行查询,例如

$entries = simplexml_load_string($xml);
$dataElements = $entries->xpath('/entries/response/resData/data[@name="dns"]');
foreach ($dataElements as $dataElement) {
    echo $dataElement;
}

上面的XPath找到name属性为"dns"的所有<data>元素,这些元素是给定元素层次结构的直接子元素,例如

 <entries>
     …
     <response>                            
         …
         <resData>                         
             …
             <data name="dns">

在我看来,这比将值复制到一个数组的额外步骤更容易和更合适,这会使它与实际的DOM树断开连接,并且您必须为所有想要以这种方式映射的元素重复。XPath是内置的。你只需查询并得到结果。

由于$dataElements是一个数组,您也可以使用

单独访问其中的元素。
echo $dataElements[0]; // prints "ns1.google.com"
echo $dataElements[1]; // prints "ns2.google.com"

注意$dataElements数组实际上包含连接到主文档的SimpleXmlElements。对它们所做的任何更改也将反映在主文档中。