Redjy Redj
Redjy Redj

Reputation: 21

How to get CDATA texts from XML by id in tags

I know how to access tags in XML using PHP but this time, I have to use a function getText($textId) to access text content in those tags but I tried so many things that I am desperate for help.

I tried this

$doc->load("localisations_EN.xml");
$texts = $doc->getElementsByTagName("txt");
$elem = $doc->getElementById("home");
$children = $elem->childNodes;

 foreach ($children as $child) {

     if ($child->nodeType == XML_CDATA_SECTION_NODE) {
           echo $child->textContent . "<br/>";
        }
} 


 print_r($texts);
 print_r($doc->getElementById('home'));


 foreach ($texts as $text) 
 {
     foreach($text->childNodes as $child) {
         if ($child->nodeType == XML_CDATA_SECTION_NODE) {
             echo $child->textContent . "<br/>";
         }

     }
 }

Then I tried this but I don't know how to access the string value

$xml=simplexml_load_file("localisations_EN.xml") or die("Error: Cannot create object");
print_r($xml);
$description = $xml->xpath("//txt[@id='home']");
var_dump($description);

And I got something like this

array(1) { [0]=> object(SimpleXMLElement)#2 (1) { ["@attributes"]=> array(1) { ["id"]=> string(4) "home" } } }

This is the XML file I have to use

<?xml version="1.0" encoding="UTF-8" ?>
<localisation application="test1">
    <part ID="menu">
        <txt id="home"><![CDATA[Home]]></txt>
        <txt id="news"><![CDATA[News]]></txt>
        <txt id="settings"><![CDATA[Settings]]></txt>
    </part>
    <part ID="login">
        <txt id="id"><![CDATA[Login]]></txt>
        <txt id="password"><![CDATA[Password]]></txt>
        <txt id="forgetPassword"><![CDATA[Forget password?]]></txt>
    </part>
</localisation>

Thanks for your help.

Upvotes: 0

Views: 571

Answers (1)

Jakumi
Jakumi

Reputation: 8374

simplexml element has a __toString() magic function that will return the text content of the element (however, not the text content of sub-elements) so your simplexml code should be

$xml=simplexml_load_file("localisations_EN.xml");
$description = (string) $xml->xpath("//txt[@id='home']")[0];
            //   ^-- triggers __toString()               ^-- xpath returns array

because xpath returns an array of elements, you need to fetch one (or more) and cast it to string. To get the immediate contents of that element.

with DOMDocument:

don't know why you go for the (non-existant) child nodes there. CDATA is just syntax to say "don't parse this, this is data"

$doc = new DOMDocument;
$doc->load("localisations_EN.xml");
$texts = $doc->getElementsByTagName('txt');
foreach($texts as $text) {
    if($text->getAttribute('id') == 'home') { 
         // prepend hasAttribute('id') if needed to if clause above
         $description = $text->textContent;
    }
}

also, $doc->getElementById() probably only works, if the DTD has set some attribute as ID. Since your xml doesn't do that (it doesn't name a DTD) it doesn't work.

with DOMDocument and DOMXPath

// $doc as before
$xpath = new DOMXPath($doc);
$description = $xpath->evaluate('//txt[@id="home"]')[0]->textContent;
// as before, xpath returns an array, that's why  ---^

Upvotes: 1

Related Questions