SimpleXML: Selecting parent node based on content of child element - php

This should be am easy task, but I just didn't get it working:
In the below code snippet, I would like to select the <WebFilterCategory> node which has a <Name> child that has a value of "Categoryname2":
<?php
$xmlstring = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<Request>
<Login>
<UserName>admin</UserName>
<Password>admin</Password>
</Login>
<Set Operation="get">
<WebFilterCategory transactionid="">
<Name>Categoryname1</Name>
<Classification>Objectionable</Classification>
<DomainList>
<Domain>example1.com</Domain>
<Domain>example2.com</Domain>
</DomainList>
</WebFilterCategory>
<WebFilterCategory transactionid="">
<Name>Categoryname2</Name>
<Classification>Objectionable</Classification>
<DomainList>
<Domain>example1.org</Domain>
<Domain>example2.org</Domain>
</DomainList>
</WebFilterCategory>
</Set>
</Request>
XML;
$xml = simplexml_load_string( $xmlstring ) or die("Error: Cannot create object");
foreach ($xml->query('//WebFilterCategory/Name[contains(., "Categoryname2")]') as $category) {
print_r($xmlstring);
}
?>
Probably, there's a much leaner query to get the desired result, too.

The method you are looking for is not query but xpath
Then you could update the path to match the WebFilterCategory where the Name contains Categoryname2
//WebFilterCategory[Name[contains(., "Categoryname2")]]'
Updated code
$xml = simplexml_load_string( $xmlstring ) or die("Error: Cannot create object");
foreach ($xml->xpath('//WebFilterCategory[Name[contains(., "Categoryname2")]]') as $category) {
print_r($category);
}
Output
SimpleXMLElement Object
(
[#attributes] => Array
(
[transactionid] =>
)
[Name] => Categoryname2
[Classification] => Objectionable
[DomainList] => SimpleXMLElement Object
(
[Domain] => Array
(
[0] => example3.org
[1] => example2.org
)
)
)
See a Php demo

Related

How parse xml sitemap with PHP?

I want to print values inside elemnts of xml file but i have a problem.
This xml sitemap:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="/sitemap.xsl"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url><loc>https://www.example.com/1</loc></url>
<url><loc>https://www.example.com/2</loc></url>
</urlset>
and this is my code:
$url_sitemap = "file.xml";
$xml_sitemap = simplexml_load_file($url_sitemap);
foreach($xml_sitemap-> urlset -> url as $url){
$link= $url->loc;
print_r($link);
}
but i have this error: Warning: Invalid argument supplied for foreach() in
If you print_r($xml_sitemap); you'll see that it doesn't contain the urlset:
SimpleXMLElement Object
(
[url] => Array
(
[0] => SimpleXMLElement Object
(
[loc] => https://www.example.com/1
)
[1] => SimpleXMLElement Object
(
[loc] => https://www.example.com/2
)
)
)
You can then use
foreach ($xml_sitemap as $url) {
echo $url->loc;
}
to output all locs

How to read xml tag, if there is another tag used in php?

I am trying to read xml tag, But there is one issue, If another tag is there inside a tag I am getting only it's attribute.
Example:
I am have a xml file
$myXMLData =
"<?xml version='1.0' encoding='UTF-8'?>
<note>
<to><hello role='admin'/>Hello World</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>";
$xml=simplexml_load_string($myXMLData) or die("Error: Cannot create object");
echo "<pre>";
print_r($xml);
Output:
SimpleXMLElement Object
(
[to] => SimpleXMLElement Object
(
[hello] => SimpleXMLElement Object
(
[#attributes] => Array
(
[role] => admin
)
)
)
[from] => Jani
[heading] => Reminder
[body] => Don't forget me this weekend!
)
But I want title "Hello World". Can anybody have a solution for this?
You can't get the value of a SimpleXML element as an object, you have to cast it to a string (or int, or ...) instead:
$myXMLData = "<title><anchor id='page1' role='first'/>Xyz Title</title>";
$xml=simplexml_load_string($myXMLData) or die("Error: Cannot create object");
echo "<pre>";
echo (string)$xml;
Output:
Xyz Title
For your revised question, just
echo (string)$xml->to;
Output:
Hello world

Remove XML child with same name

I have a large XML with the following:
<?xml version="1.0" encoding="UTF-8"?>
<valasz xmlns="" verzio="1.0">
<arak>
<ar>
<cikkid>439902</cikkid>
<cikkszam>DVDV-16Z10</cikkszam>
<listaar>1225,0000000</listaar>
<ar>1157,6200000</ar>
<akcios_ar>1157,6200000</akcios_ar>
<devizanem>HUF</devizanem>
</ar>
<ar>
..
<ar>1157,6200000</ar>
...
</ar>
</arak>
What i want is to remove arak->ar->ar child because its causing in the import it looks like duplicates, and slowing down the process.
I have tried the following:
$node = readfile($arlista[0]);
$nodes = simplexml_load_string($node);
$arnode = $nodes->xpath("/valasz/arak/ar/ar");
foreach ($arnode as &$ar){
$nodes->removeChild($ar);
}
echo $nodes;
And this only returns me the original xml, without removing the arak->ar->ar child nodes.
What am i doing wrong?
There is no such thing as ::removeChild() in SimpleXML.
What you want do do in your foreach loop is this:
foreach ($arnode as $ar){
unset($ar->{0});
}
Please note: The posted XML is not valid but I am sure that is just some kind of copy&paste flaw
Complete code:
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<valasz xmlns="" verzio="1.0">
<arak>
<ar>
<cikkid>439902</cikkid>
<cikkszam>DVDV-16Z10</cikkszam>
<listaar>1225,0000000</listaar>
<ar>1157,6200000</ar>
<akcios_ar>1157,6200000</akcios_ar>
<devizanem>HUF</devizanem>
</ar>
<ar>
<ar>1157,6200000</ar>
</ar>
</arak>
</valasz>';
$nodes = simplexml_load_string($xml);
$arnode = $nodes->xpath("/valasz/arak/ar/ar");
foreach ($arnode as $ar){
unset($ar->{0});
}
print_r($nodes);
Returns this
SimpleXMLElement Object
(
[#attributes] => Array
(
[verzio] => 1.0
)
[arak] => SimpleXMLElement Object
(
[ar] => Array
(
[0] => SimpleXMLElement Object
(
[cikkid] => 439902
[cikkszam] => DVDV-16Z10
[listaar] => 1225,0000000
[akcios_ar] => 1157,6200000
[devizanem] => HUF
)
[1] => SimpleXMLElement Object
(
)
)
)
)

GPX file parse with PHP, get <extensions> element values

i have xml/gpx file:
<?xml version="1.0" encoding="utf-8"?>
<gpx xsi:schemaLocation="http://www.topografix.com/GPX/1/1">
<metadata>
....
</metadata>
<trk>
<trkseg>
<trkpt lat="50.04551333333333" lon="14.434101666666667">
<ele>282</ele>
<time>2014-06-30T20:56:03.92</time>
<extensions>
<gpxtpx:TrackPointExtension>
<gpxtpx:hr>100</gpxtpx:hr>
</gpxtpx:TrackPointExtension>
</extensions>
</trkpt>
...
</gpx>
Load:
$xml=simplexml_load_file($gpx_file);
parse witch
foreach($xml->trk->trkseg->trkpt as $point){}
Thats fine. But i cant get content of /extension//extension/
print_r($point) is
SimpleXMLElement Object
(
[#attributes] => Array
(
[lat] => 50.04527
[lon] => 14.433993333333333
)
[ele] => 280.5
[time] => 2014-06-30T20:57:21.71
[extensions] => SimpleXMLElement Object
(
)
)
and i cannot get SimpleXMLElement Object.
Print_r($point->extension is:
SimpleXMLElement Object
(
)
I try Converting a SimpleXML Object to an Array and other similiar way, but i have failed - output is empty array.
Any idea/way to get into string/array ?
Sample gpx is on www.vovcinec.net/gpx/e.gpx (~700kB)
You can't get them directly since they are in namespaces, you need to use getNamespaces() method first. Consider this example:
$xml = simplexml_load_file('e.gpx');
foreach($xml->trk->trkseg->trkpt as $trkpt) {
$namespaces = $trkpt->getNamespaces(true);
$gpxtpx = $trkpt->extensions->children($namespaces['gpxtpx']);
$hr = (string) $gpxtpx->TrackPointExtension->hr;
echo '<pre>';
print_r($hr);
echo '</pre>';
}
I hope you help following code
foreach($gpx->trk->trkseg->children() as $trkpts) {
echo (string)$trkpts->extensions->children('gpxtpx',true)->TrackPointExtension->hr;
}
no need to use getNamespaces() method

PHP - get values from xml

I have a some problem with get value from xml.
XML look like
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="http://crd.gov.pl/xml/schematy/UPO/2008/05/09/UPO.xsl"?>
<pos:Document xmlns:pos="SOMEURL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<pos:DescribeDoc/>
<pos:UPD>
<pos:IdDoc>procotol-UPD2198338</pos:IdDoc>
<pos:IdCases>221872</pos:IdCases>
<pos:additionalInfo TypeInfo="Source">Some string</pos:additionalInfo>
</pos:UPD>
...
I general try to get to pos:IdCases.
I try this code:
$domContent = new SimpleXMLElement(((string) $content), LIBXML_COMPACT);
$test = $domContent->xpath('/pos:Document/pos:UPD/*');
foreach($test as $node){
print_r($node)
}
I get a some object such as
SimpleXMLElement Object
(
[0] => procotol-UPD2198338
)
SimpleXMLElement Object
(
[0] => 221872
)
SimpleXMLElement Object
(
[#attributes] => Array
(
[TypeInfo] => Source
)
[0] => Some string
)
But I must get to pos:IdCases. I can't use index [1] because order can change.
My question is:
How can I get to value in node: pos:IdCases
I can't add id or another info to node because this xml was signed (XADES).
Can you give me some advice? Thanks for help
Simply change the XPath to match the <Pos:IdCases/> node:
$test = $domContent->xpath('/pos:Document/pos:UPD/pos:IdCases');

Categories