开发者

PHP & XML Read element by attribute value

开发者 https://www.devze.com 2023-04-09 01:10 出处:网络
$xml = \'<?xml version=\"1.0\"?> <entries> <response> <category>client</category>
$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];

With the above code i can get the values. But how can i get the values by attribute value?

For example i want to get the values with something like this:

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

One more question.

If i have two elements with the same name? For example i would like to parse the dns. How could i do it?

The xml code is like this:

    <?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>

As you can see the ns1 and ns2 have the same name. name="dns". How can i parse each one in a different variable?

Thank you!


With the element["attribute"] syntax, attribute is the name of an attribute on the element. It is not the value of some randomly chosen attribute belonging to an element.

The example below creates an array containing a mapping for the data elements of name attribute value to text value.

$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, your code expects XML structured like:

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

Edit due to question change

In a marvelous dose of eating my own words, due to the change in the question an XPath approach would be more appropriate (don't you love OPs who do that?).

You can easily get an array of the name="dns" elements with a basic XPath expression.

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


You can use XPath to to do queries against your XML, e.g.

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

The above XPath finds all <data> elements with a name attribute of "dns" that are direct children of the given element hierarchy, e.g.

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

IMO this is easier and more appropriate than having the extra step of copying over the values into an array which would disconnect it from the actual DOM tree and which you would have to repeat for all the elements you want to map this way. XPath is built-in. You just query and get the result.

Because $dataElements is an array, you can also access the elements in it individually with

echo $dataElements[0]; // prints "ns1.google.com"
echo $dataElements[1]; // prints "ns2.google.com"

Note that the $dataElements array actually contains SimpleXmlElements connected to the main document. Any changes you do to them will also be reflected in the main document.

0

精彩评论

暂无评论...
验证码 换一张
取 消