The structure of my XML file is:
<?xml version="1.0" encoding="UTF-8"?>
....
..
.
<usernames>
<user id="harrypotter">
<topicid id="1">
<commentid>1</commentid>
</topicid>
<topicid id="2">
<commentid>2</commentid>
</topicid>
<topicid id="3">
<commentid>3</commentid>
</topicid>
<topicid id="4">
<commentid>4</commentid>
</topicid>
<topicid id="5">
<commentid>5</commentid>
</topicid>
<topicid id="6">
<commentid>6</commentid>
</topicid>
<topicid id="7">
<commentid>7</commentid>
</topicid>
<topicid id="8">
<commentid>8</commentid>
</topicid>
<topicid id="9">
<commentid>9</commentid>
</topicid>
<topicid id="10">
<commentid>10</commentid>
</topicid>
<topicid id="11">
<commentid>11</commentid>
</topicid>
</user>
....
..
.
</usernames>
I have a function to get a comment by passing a topic, and a username. My function is:
function getComment($var_topicid, $usrname)
$xml2=simplexml_load_file("comment.xml") or die("Error: Cannot create object");
foreach ($xml2->user as $user){
if ($user['id'] == $usrname){
if($user->topicid['id'] == $var_topicid){
return $user->topicid->commentid;
}
}
}
}
I try to get a comment by passing the values, but it does not return anything.
$x = getComment('2','harrypotter'));
print $x;
Could you please give some suggestion?
Thank you.
I found a solution by applying xpath:
$myDataObjects = $xml2->xpath('//usernames/user[#id="harrypotter"]/topicid[#id="2"]/commentid');
print $myDataObjects[0][0];
More details: SimpleXML: Selecting Elements Which Have A Certain Attribute Value
Also you're not looping on the user nodes : the topicid, you should add a foreach, it should look like this :
function getComment($var_topicid, $usrname)
$xml2=simplexml_load_file("comment.xml") or die("Error: Cannot create object");
foreach ($xml2->user as $user){
if ($user['id'] == $usrname){
foreach (user->topicid as $topic){
if($topic['id'] == $var_topicid){
return $topic->commentid;
}
}
}
}
}
Related
I have a sophisticated feed that I want to echo the values of the XML file to PHP table.
Below is a sample of the UK RailDataFeed (Aka Darwin).
<?xml version="1.0" encoding="UTF-8"?>
<Pport xmlns="http://www.thalesgroup.com/rtti/PushPort/v12" xmlns:ns3="http://www.thalesgroup.com/rtti/PushPort/Forecasts/v2" ts="2018-01-01T21:58:48.2213864Z" version="12.0">
<uR updateOrigin="Trust">
<TS>
<Location pta="21:59" ptd="21:59" tpl="ROBY" wta="21:59" wtd="21:59:30">
<arr at="21:59" src="TRUST" srcInst="Auto" />
<dep et="21:59" src="Darwin" />
<plat conf="true" platsrc="A">4</plat>
</Location>
<Location pta="22:06" ptd="22:06" tpl="PRESCOT" wta="22:05:30" wtd="22:06">
<arr et="22:06" src="Darwin" wet="22:05" />
<dep et="22:06" src="Darwin" />
<plat>1</plat>
</Location>
</TS>
</uR>
</Pport>
I have been trying and researching all day to try to get the echo working but without any luck, I have tried the following
Test (1)
$xml=simplexml_load_file("log.xml") or die("Error: Cannot create object");
echo $xml->Location[0]['tpl'] . "<br>";
echo $xml->Location[1]->arr['at'];
echo $xml->Location[2]->dep['et'];
echo $xml->Location[3]->plat;
Test (2)
$xml=simplexml_load_file("log.xml") or die("Error: Cannot create object");
foreach($xml->children() as $loc) {
echo $loc->Location['tpl'];
echo $loc->arr['at'];
echo $loc->plat;
echo "<br>";
}
Test (3)
$file = file_get_contents('log.xml');
echo $file;
Still without any progress, After achieving this, I want to add the values to a bootstrap table too.
If any Ideas please share with me.
You can access attribute values via the attributes() method. Also, note that values are cast to string when echoing.
$str = <<<EOF
<?xml version="1.0" encoding="UTF-8"?>
<Pport xmlns="http://www.thalesgroup.com/rtti/PushPort/v12" xmlns:ns3="http://www.thalesgroup.com/rtti/PushPort/Forecasts/v2" ts="2018-01-01T21:58:48.2213864Z" version="12.0">
<uR updateOrigin="Trust">
<TS>
<Location pta="21:59" ptd="21:59" tpl="ROBY" wta="21:59" wtd="21:59:30">
<arr at="21:59" src="TRUST" srcInst="Auto" />
<dep et="21:59" src="Darwin" />
<plat conf="true" platsrc="A">4</plat>
</Location>
<Location pta="22:06" ptd="22:06" tpl="PRESCOT" wta="22:05:30" wtd="22:06">
<arr at="22:06" src="Darwin" wet="22:05" />
<dep et="22:06" src="Darwin" />
<plat>1</plat>
</Location>
</TS>
</uR>
</Pport>
EOF;
$xml = simplexml_load_string($str);
$c = 0;
foreach($xml->uR->TS->Location as $loc) {
echo (++$c) . "\n";
echo (string)$loc->attributes()['tpl'] . "\n";
echo (string)$loc->arr->attributes()['at'] . "\n";
echo (string)$loc->dep->attributes()['et'] . "\n\n";
}
After #marekful reply.
code modified to
<?php
$str = file_get_contents('log.xml');
$xml = simplexml_load_string($str);
$c = 0;
foreach($xml->uR->TS->Location as $loc)
{
echo (++$c) . "\n";
echo (string)$loc->attributes()['tpl'] . "\n";
echo (string)$loc->arr->attributes()['at'] . "\n";
echo (string)$loc->dep->attributes()['et'] . "\n\n";
echo (string)$loc->plat . "\n\n\n";
}
?>
And it worked perfectly with the sample xml file, but after adding the original XML file, It has multiple header in the file itself as shown below:
<?xml version="1.0" encoding="UTF-8"?>
<Pport xmlns="http://www.thalesgroup.com/rtti/PushPort/v12" xmlns:ns3="http://www.thalesgroup.com/rtti/PushPort/Forecasts/v2" ts="2018-01-03T01:31:28.3036616Z" version="12.0">
<uR requestID="AM02050384" requestSource="AM02" updateOrigin="CIS">
<TS rid="201801037171519" ssd="2018-01-03" uid="G71519">
<ns3:Location tpl="GLYNDE" wtp="01:25:08">
<ns3:pass at="01:31" src="TD" />
<ns3:plat conf="true" platsrc="A" platsup="true">2</ns3:plat>
<ns3:length>8</ns3:length>
</ns3:Location>
</TS>
</uR>
</Pport>
<?xml version="1.0" encoding="UTF-8"?>
<Pport xmlns="http://www.thalesgroup.com/rtti/PushPort/v12" xmlns:ns3="http://www.thalesgroup.com/rtti/PushPort/Forecasts/v2" ts="2018-01-03T01:31:29.1772672Z" version="12.0">
<uR requestID="0000000000046386" requestSource="at21" updateOrigin="CIS">
<TS rid="201801038706030" ssd="2018-01-03" uid="W06030">
<ns3:Location pta="01:25" ptd="01:26" tpl="DARTFD" wta="01:25" wtd="01:26">
<ns3:arr at="01:31" src="TD" />
<ns3:dep et="01:32" etmin="01:27" src="Darwin" />
<ns3:plat conf="true" platsrc="A">4</ns3:plat>
</ns3:Location>
</TS>
</uR>
</Pport>
<?xml version="1.0" encoding="UTF-8"?>
<Pport xmlns="http://www.thalesgroup.com/rtti/PushPort/v12" xmlns:ns3="http://www.thalesgroup.com/rtti/PushPort/Forecasts/v2" ts="2018-01-03T01:31:30.1912737Z" version="12.0">
<uR updateOrigin="TD">
<TS rid="201801027160109" ssd="2018-01-02" uid="G60109">
<ns3:Location tpl="BRINKLW" wtp="01:34:30">
<ns3:pass at="01:31" src="TD" /></ns3:Location>
</TS>
</uR>
</Pport>
<?xml version="1.0" encoding="UTF-8"?>
<Pport xmlns="http://www.thalesgroup.com/rtti/PushPort/v12" xmlns:ns3="http://www.thalesgroup.com/rtti/PushPort/Forecasts/v2" ts="2018-01-03T01:31:31.2052802Z" version="12.0">
<uR updateOrigin="TD">
<TS rid="201801036763188" ssd="2018-01-03" uid="C63188">
<ns3:Location tpl="AMBERGJ" wtp="02:04:30">
<ns3:pass et="01:38" src="TD" /></ns3:Location>
</TS>
</uR>
</Pport>
Is there a way to:
Ignore the multiple headers to avoid errors.
Post the echo value to a Bootstrap table.
Cheers!
I want to delete a node by id in XML my code is this:
$id=$_GET["id"];
$usuarios= simplexml_load_file('cart.xml');
if($_GET["action"] == "delete"){
foreach($usuarios->carro as $elemento){
if($elemento['id'] == $id) {
echo '<script>alert("delete")</script>';
unset($elemento['id']);
}
}
}
but doesn't work.
My XML cart.xml:
<?xml version="1.0"?>
<info>
<carro id="0">
<usuario>alex</usuario>
<producto>instict</producto>
<Size>CH</Size>
<cantidad>1</cantidad>
<precio>100</precio>
</carro>
<carro id="1">
<usuario>alex</usuario>
<producto>instict</producto>
<Size>G</Size>
<cantidad>1</cantidad>
<precio>100</precio>
</carro>
<carro id="2">
<usuario>alex</usuario>
<producto>instict</producto>
<Size>G</Size>
<cantidad>1</cantidad>
<precio>100</precio>
</carro>
<carro id="3">
<usuario>Gera</usuario>
<producto>instict</producto>
<Size>M</Size>
<cantidad>1</cantidad>
<precio>100</precio>
</carro>
</info>
I want to delete for example id="2" so the output would be:
<?xml version="1.0"?>
<info>
<carro id="0">
<usuario>alex</usuario>
<producto>instict</producto>
<Size>CH</Size>
<cantidad>1</cantidad>
<precio>100</precio>
</carro>
<carro id="1">
<usuario>alex</usuario>
<producto>instict</producto>
<Size>G</Size>
<cantidad>1</cantidad>
<precio>100</precio>
</carro>
<carro id="3">
<usuario>Gera</usuario>
<producto>instict</producto>
<Size>M</Size>
<cantidad>1</cantidad>
<precio>100</precio>
</carro>
</info>
Change
$usuarios->carro as $key => $elemento
and then
unset($usuarios->carro[$key]);
and then write result in new file as string
file_put_contents('newfile.xml', $usuarios->asXML());
XML:
<Result xmlns="" xmlns:xsi="" totalResultsAvailable="0" totalResultsReturned="0" schk="true" totalLooseOffers="0" xsi:schemaLocation="">
<details>
<ID></ID>
<applicationVersion>1.0</applicationVersion>
<applicationPath/>
<date>2016-05-23T12:17:16.369-03:00</date>
<elapsedTime>17</elapsedTime>
<status>success</status>
<message>success</message>
</details>
<category id="1">
<thumbnail url="http://image.google.com/test.jpg"/>
<links>
<link url="www.google.com" type="category"/>
<link url="www.google2.com" type="xml"/>
</links>
<name>Category</name>
<filters>
<filter id="1" name="Filter1">
<value id="1" value="Test1"/>
<value id="2" value="Test2"/>
<value id="3" value="Test3"/>
</filter>
<filter id="2" name="Filter2">
<value id="1" value="Test4"/>
<value id="2" value="Test5"/>
<value id="3" value="Test6"/>
</filter>
</filters>
</category>
</Result>
PHP:
$xml = simplexml_load_file("http://xml.com");
foreach($xml->category->filters as $filters){
foreach($filters->children() as $child){
echo $child['value'];
}
}
I'm trying to get the filters value, but nothing shows with the code i have. I saw something about xpath but don't know if it's applicable in this situation. Do you have any clue?
--
When the XML looks like this:
<Result xmlns="" xmlns:xsi="" totalResultsAvailable="0" totalResultsReturned="0" schk="true" totalLooseOffers="0" xsi:schemaLocation="">
<details>
<ID></ID>
<applicationVersion>1.0</applicationVersion>
<applicationPath/>
<date>2016-05-23T12:17:16.369-03:00</date>
<elapsedTime>17</elapsedTime>
<status>success</status>
<message>success</message>
</details>
<subCategory id="1">
<thumbnail url="http://image.google.com/test.jpg"/>
<name>Subcategory</name>
</subCategory>
<subCategory id="2">
<thumbnail url="http://image.google.com/test2.jpg"/>
<name>Subcategory2</name>
</subCategory>
</Result>
Then am able to do this:
foreach($xml->subCategory as $subCategory){
$categoryId = $subCategory['id'];
$categoryName = $subCategory->name;
}
The elements you reference as $child in the inner loop actually point to the <filter> nodes, not the children <value> nodes you are attempting to target attributes for. So this really is just a matter of extending the outer foreach loop to iterate over $xml->category->filters->filter rather than its parent $xml->category->filters.
// Iterate the correct <filter> node, not its parent <filters>
foreach ($xml->category->filters->filter as $filter) {
foreach($filter->children() as $child){
echo $child['value'] . "\n";
}
}
Here it is in demonstration: https://3v4l.org/Rqc4Y
Using xpath, you can target the inner nodes directly.
$values = $xml->xpath('//category/filters/filter/value');
foreach ($values as $value) {
echo $value['value'];
}
https://3v4l.org/vPhKE
Both of these examples output
Test1
Test2
Test3
Test4
Test5
Test6
I want to be able to to delete a node tree if a specific child is empty, but seems to do something wrong?
Here is what I got:
$xml = new DOMDocument();
$xml->loadXML('<?xml version="1.0" encoding="ISO-8859-1"?>
<data>
<game id="1">
<opponent>Michael</opponent>
<oppid>1</oppid>
</game>
<game id="2">
<opponent>Trish</opponent>
<oppid>55</oppid>
</game>
<game id="3">
<opponent/>
<oppid>24</oppid>
</game>
<game id="4">
<opponent>Betty</opponent>
<oppid>12</oppid>
</game>
</data>
');
echo "<xmp>OLD \n". $xml->saveXML() ."</xmp>";
$xpath = new DOMXpath($xml);
foreach($xpath->query('//game') as $node) {
if($node->opponent == ''){
echo 'Test<br>';
$node->parentNode->removeChild($node);
}
}
echo "<xmp>NEW \n". $xml->saveXML() ."</xmp>";
I get 4 "Test" printed out and in the NEW xmp I get nothing? What am I doing wrong?
Please help and thanks in advance.
<?php
$xml = new DOMDocument();
$xml->loadXML('<?xml version="1.0" encoding="ISO-8859-1"?>
<data>
<game id="1">
<opponent>Michael</opponent>
<oppid>1</oppid>
</game>
<game id="2">
<opponent>Trish</opponent>
<oppid>55</oppid>
</game>
<game id="3">
<opponent/>
<oppid>24</oppid>
</game>
<game id="4">
<opponent>Betty</opponent>
<oppid>12</oppid>
</game>
</data>
');
echo "<xmp>OLD \n". $xml->saveXML() ."</xmp>";
$opNodes = $xml->getElementsByTagName('opponent');
foreach($opNodes as $node) {
$innerHtml = trim($node->nodeValue);
if(empty($innerHtml)){
$gameNode = $node->parentNode;
$gameNode->parentNode->removeChild($gameNode);
}
}
echo "<xmp>NEW \n". $xml->saveXML() ."</xmp>";
i wonder why it was not working... now it works .
Change your if condition to following:
if($node->opponent->nodeValue == '')
Recently I have been working with the xml coding,and the problem happened.
Given the xml like this:
<Colonel id="1">
<Lieutenant_Colonel id="2">
<Secretary id="6"/>
</Lieutenant_Colonel>
<Lieutenant_Colonel id="3">
<Secretary id="7"/>
</Lieutenant_Colonel>
<Secretary id="5"/>
</Colonel>
now the Colonel(id=1) has gone with the Secretary(id=5)
the xml we want is like
<!-- <Colonel id="1"> -->
<Lieutenant_Colonel id="2">
<Secretary id="6"/>
</Lieutenant_Colonel>
<Lieutenant_Colonel id="3">
<Secretary id="7"/>
</Lieutenant_Colonel>
<!--
<Secretary id="5"/>
</Colonel> -->
or
<Lieutenant_Colonel id="2">
<Secretary id="6"/>
</Lieutenant_Colonel>
<Lieutenant_Colonel id="3">
<Secretary id="7"/>
</Lieutenant_Colonel>
How to do this work?
please help me
This is a pretty long them, so I´ll have to refer other questions. First, consider this function:
function RemoveColonel($id, $secretaryId)
{
$colXpath = '//colonel[#id="' . $id . '"]';
$secXpath = $colXpath . '/Secretary[#id="' . $secretaryId . '"]';
RemoveNode($secXpath);
$colChildren = $rootXml->xpath($colXpath)->children();
$children = array();
foreach ($colChildren as $child ){
$children[] = $child;
}
RemoveNode($colXpath);
return $children;
}
Given the Id of a colonel and a secretary for that colonel, it deletes the secretary, then it saves the colonel's children to remove the colonel and return the children. After that, you can insert your elements in the root node again if you please. If you can't have the secretary Id at the moment of deleting the colonel, you can workaround the xpath to remove the secretary as child of the colonel by removing the id specification.
The RemoveNode code is a bit long, so I'll have to give you this question on how to remove nodes using SimpleXML in PHP.
I hope I can be of some help!