Search code examples
phpxmlsimplexml

Get attribute values SimpleXML Xpath PHP


<RESULTS>
    <ROW>
        <COLUMN NAME="ID"><![CDATA[001]]></COLUMN>
        <COLUMN NAME="NAME"><![CDATA[ORG001]]></COLUMN>
        <COLUMN NAME="CODE"><![CDATA[1234]]></COLUMN>
    </ROW>
</RESULTS>

Using simplexml / xpath i would like to return the attribute text for 'NAME' and 'CODE' for ID 001, there is many rows so the result would be different based on id number

Edit: accessing the CDATA isn't the problem here, it is returning the values of name and code where id = 001 etc

heres what i tried to get the name

echo (string)$xml->xpath('/RESULT/ROW/COLUMN[@ID] = ["001"]/COLUMN[@Name="NAME"]');

Thanks


Solution

  • Not sure what you really try to do. As far as I understand...

    $xml = simplexml_load_string($x); // assuming XML in $x
    $hit = (string)$xml->xpath("/RESULTS/ROW[COLUMN/@NAME='ID' and COLUMN/text() = '001']/COLUMN[@NAME='NAME']")[0];
    

    Above code step by step:

    • (string) will force the result to string, instead of object
    • xpath-expression: get <ROW> with a child <COLUMN> with an attribute NAME='ID' and a value of 001
    • starting from that specific <ROW>, select a child <COLUMN> with an attribute of NAME='NAME'
    • xpath() returns an array of SimpleXml elements, by [0] we select its first entry.
    • be aware that this code lacks checking if there's a match at all.

    see it working: https://eval.in/503464

    EDIT:
    Re-read the question. To get the result you want, select the <ROW> and then iterate over the <COLUMN>:

    $hit = $xml->xpath("/RESULTS/ROW[COLUMN/@NAME='ID' and COLUMN/text() = '001']")[0];
    foreach ($hit as $column)
        echo $column['NAME'] . ": " . $column . PHP_EOL;
    

    Output:

    ID: 001
    NAME: ORG001
    CODE: 1234
    

    see https://eval.in/503493