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());
Related
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
want to make loop and Parsing XML CDATA
my XML
<?xml version="1.0"?>
<photos>
<photo image="images/1.jpg" url="http://LINKHERE" target="_blank" id="1">
</photo>
<photo image="images/1.jpg" url="http://LINKHERE" target="_blank" id="2">
</photo>
</photos>
my code
for ($x = 1; $x <= 10; $x++) {
$dom=new DOMDocument();
$xml='images.xml';
$dom->load($xml);
$xp = new DomXPath($dom);
//$item_content = $xp->query("//*[#id = $x]");
foreach ($dom->getElementsByTagName('photos') as $item) {
$cdata=$dom->createCDATASection('<head>test'.$x.'</head><body></body>');
$item->getElementsByTagName('photo')->item(0)->appendChild($cdata);
}
$dom->save($xml);
}
but the result
<photo image="images/1.jpg" url="http://LINKHERE" target="_blank" id="1">
<![CDATA[<head>test1</head><body></body><head>test2</head><body></body><head>test3</head><body></body>
<head>test4</head><body></body><head>test5</head><body></body>
<head>test6</head><body></body><head>test7</head>
<body></body><head>test8</head><body></body><head>test9</head><body></body>]]><![CDATA[<head>test10</head><body>
</body>]]></photo>
<photo image="images/2.jpg" url="http://http://LINKHERE" target="_blank" id="2">
</photo>
i want it be this
<photo image="images/1.jpg" url="http://LINKHERE" target="_blank" id="1">
<![CDATA[<head>test1</head><body></body>]]></photo>
<photo image="images/2.jpg" url="http://http://LINKHERE" target="_blank" id="2">
<![CDATA[<head>test2</head><body></body>]]></photo>
i want move on loop by id
i try many times but no way , i think i have a problem on my loop
need some help here
You want to append CData on each photo element, so you should loop through photo instead of photos, for example :
$raw = <<<XML
<photos>
<photo image="images/1.jpg" url="http://LINKHERE" target="_blank" id="1">
</photo>
<photo image="images/1.jpg" url="http://LINKHERE" target="_blank" id="2">
</photo>
</photos>
XML;
$dom = new DOMDocument();
$dom->loadXML($raw);
$x = 1;
foreach ($dom->getElementsByTagName('photo') as $item) {
$cdata=$dom->createCDATASection('<head>test'.$x.'</head><body></body>');
$item->appendChild($cdata);
$x++;
}
echo $dom->saveXML($xml);
eval.in demo
output :
<?xml version="1.0"?>
<photos>
<photo image="images/1.jpg" url="http://LINKHERE" target="_blank" id="1">
<![CDATA[<head>test1</head><body></body>]]></photo>
<photo image="images/1.jpg" url="http://LINKHERE" target="_blank" id="2">
<![CDATA[<head>test2</head><body></body>]]></photo>
</photos>
Try this code
<?php
$dom=new DOMDocument();
$xml='images.xml';
$dom->load($xml);
$xp = new DomXPath($dom);
$i = 0;
foreach ($dom->getElementsByTagName('photo') as $item) {
$cdata=$dom->createCDATASection('<head>test'.($i+1).'</head><body></body>');
$item->appendChild($cdata);
$i ++;
}
$dom->save($xml);
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;
}
}
}
}
}
I am trying to convert an XML-file through a PHP-script. I have the following structure:
<?xml version="1.0"?>
<persons>
<person id="1">
<periods>3</periods>
<name id="John"/>
<times>
<time>
<day id="1"/>
<time>35:28</time >
<length>8000</length>
</time>
<time>
<day id="4"/>
<time>8:28</time >
<length>2000</length>
</time>
<time>
<day id="5"/>
<time>3:03</time >
<length>1000</length>
</time>
</times>
</person>
<person id="2">
<periods>3</periods>
<name id="James"/>
<times>
<time>
<day id="3"/>
<time>45:20</time >
<length>15000</length>
</time>
<time>
<day id="5"/>
<time>4:48</time >
<length>1500</length>
</time>
</times>
</person>
etc…
etc…
</persons>
Every person has one or more time-elements. I want to convert the structure so I get only one time-element per person-element (like the structure below).
<?xml version="1.0"?>
<persons>
<person id="1">
<periods>3</periods>
<name id="John"/>
<times>
<time>
<day id="1"/>
<time>35:28</time >
<length>8000</length>
</time>
</times>
</person>
<person id="1">
<periods>3</periods>
<name id="John"/>
<times>
<time>
<day id="4"/>
<time>8:28</time >
<length>2000</length>
</time>
</times>
</person>
<person id="1">
<periods>3</periods>
<name id="John"/>
<times>
<time>
<day id="5"/>
<time>3:03</time >
<length>1000</length>
</time>
</times>
</person>
<person id="2">
<periods>2</periods>
<name id="James"/>
<times>
<time>
<day id="3"/>
<time>45:20</time >
<length>15000</length>
</time>
</times>
</person>
<person id="2">
<periods>2</periods>
<name id="James"/>
<times>
<time>
<day id="5"/>
<time>4:48</time >
<length>1500</length>
</time>
</times>
</person>
</persons>
Is there a way to do this?
I really know English very bad, but I'll try to answer :)
I think, that for the implementation of this task will suit SimpleXml and Dom extensions.
The following is a simple script that does the required transformation.
input.xml is the file with source text.
The result of the algorithm will be saved to output.xml file.
<?php
$simpleXml = new SimpleXMLElement(file_get_contents('input.xml'));
$personElements = $simpleXml->person;
$personForAppend = array();
$personsForRemove = array();
foreach ($personElements as $personElement) {
$timeElements = $personElement->times->xpath("child::time");
$numberOfTimeElements = count($timeElements);
if ($numberOfTimeElements > 1) {
$personDomElement = dom_import_simplexml($personElement);
$backupTimeDomElementArray = array();
foreach ($timeElements as $timeElement) {
$timeDomElement = dom_import_simplexml($timeElement);
$backupTimeDomElementArray[] = clone $timeDomElement;
$timeDomElement->parentNode->removeChild(
$timeDomElement
);
}
while ($timeDomElement = array_shift($backupTimeDomElementArray)) {
$copyPersonDomElement = clone $personDomElement;
$copyPersonDomElement->getElementsByTagName('times')
->item(0)->appendChild($timeDomElement);
$personForAppend[] = $copyPersonDomElement;
}
$personsForRemove[] = $personDomElement;
}
}
foreach ($personForAppend as $personDomeNode) {
$personDomElement->parentNode->appendChild($personDomeNode);
}
foreach ($personsForRemove as $personDomElement) {
$personDomElement->parentNode->removeChild($personDomElement);
}
$simpleXml->saveXML('output.xml');
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 == '')