PHP& XML按属性值读取元素

时间:2011-09-29 09:42:15

标签: php xml

$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”。 我如何用不同的变量解析每个变量?

谢谢!

2 个答案:

答案 0 :(得分:1)

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

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

$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方法会更合适(你不喜欢OP那样做吗?)。

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

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

答案 1 :(得分:0)

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

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

上述XPath查找具有{d}的<data>属性的所有name元素,它们是给定元素层次结构的直接子元素,例如

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

IMO这比将值复制到数组中的额外步骤更容易也更合适,这会将它与实际的DOM树断开连接,并且您必须为这种方式映射的所有元素重复这些步骤。 XPath是内置的。您只需查询并获得结果。

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

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

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