I'm not sure if it's possible or not, but here is what I would like to be able to do.
My xml file structure:
<?xml version="1.0" encoding="utf-8" ?>
<content>
<option name="0">Yes</option>
<option name="1">No</option>
<option name="2">Maybe</option>
</content>
I would like to update only one node at the time, for example:
Replace word "Maybe" with something else, where value == 2. So it needs to search for "option name="2" and replace word Maybe with user input.
You can do that with simplexmland xpath:
$xml = simplexml_load_string($x); // assume XML in $x
// get the node
$node = $xml->xpath("/content/option[#name = '2']");
// change it
$node[0][0] = "Hello!";
see it working: https://eval.in/127855
Related
I have an XML file with the root element name wwwjob. This root element contains attributes, I need to access the value of the 'method' attribute to be able to update various database entries.
This is a little bit of a learning curve at the moment.
<?xml version="1.0" encoding="iso-8859-1"?>
<wwwjob id="32cca11IACH" method="Delete">
some more xml stuff
</wwwjob>
Ive tried:
<?php $xml = $vacancyXML->wwwjob['method']; ?>
This just gave me 'NULL'.
Ive also tried:
<?php $xml = $vacancyXML->getName(); ?>
This just spits out the name 'wwwjob'.
I need to store the method (Delete/Update/Add) as a variable for use in later parts of the function.
Thanks
When loadinG to simplexml, attributes of the root element became attributes of the simpleXml object. So, you can get it just
$str = '<?xml version="1.0" encoding="iso-8859-1"?>
<wwwjob id="32cca11IACH" method="Delete">
</wwwjob>';
$vacancyXML = simplexml_load_string($str);
echo $vacancyXML['method']; // Delete
demo
You can get the attributes of the root element with SimpleXMLElement::attributes():
$www = new SimpleXMLElement($xml);
echo $www->attributes()->method; // Delete
Demo
I got a problem when I set a value/attribute of XML tag.
This is my PHP code:
$f=simplexml_load_file("String.xml");
$f2=$f->imgdir;
foreach($f2 as $imgdir)
{
$st=$imgdir->string;
foreach($st as $str)
{
$fd=$str->attributes();
$fd['value']='New Value';
}
}
$f->asXML("String.xml");
And this is my String.xml file's content:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<imgdir name="Cash.img">
<imgdir name="5000011">
<string name="name" value="Monkey"/>
<string name="desc" value="A lovely effect that shows a baby angel floating around as your protector. Designate a HotKey to turn the effect on/off."/>
</imgdir>
<imgdir name="5010000">
<string name="name" value="Sunny Day"/>
<string name="desc" value="A special effect in which you'll see a brightly smiling sun floating over you. On the KeyConfig, configure this on a button of your choice to turn the effect on/off."/>
</imgdir>
</imgdir>
How can I change the value attribute of per <string> tag and save the XML file? What should I do with my current code?
Thank for reading my question!
Basics
I suggest you select all <string> nodes with xpath:
$xml = simplexml_load_string($x); // assume XML in $x
$strings = $xml->xpath("//string");
The above statement will select all <string> nodes as SimpleXml elements into an array.
The double slash in //string will take <string> regardless of their position in the tree.
Now it is simple to iterate over $strings and set the new value:
foreach ($strings as $string)
$string["value"] = "new value";
Note that the changes applied to $strings happen in $xml, so:
echo $xml->asXML();
will show the changes.
see it working: https://eval.in/499427
Expanded
Of course, you might want to select only certain <string> nodes, e.g. all having name="name". In this case, you can tell xpath like:
$strings = $xml->xpath("//string[#name='name']");
Note the condition set in [] and #name referring to the attribute name.
I am have two xml files.. I first get one and loop through it then I need to take an id from the first xml file and find it in the second one and echo out the results associated with that id. If I were to do this with SQL I would simply do this:
$query = (SELECT * FROM HotelSummary WHERE roomTypeCode = '$id') or die();
while($row=mysql_fetch_array($query)){
$name = $row['Name'];
}
echo $name;
How can I do this is in xml and php??
I recommend you to read the DOMDocument documentation.
It's quite heavy but also powerful (not always clear what happens, but the Internet shold always give you a solution)
You can simply walk through your first document, finding your Id and then find your DOMElement via an XPath.
<?php
$dom = new DOMDocument();
$dom->load('1.xml');
foreach ($dom->getElementsByTagName('article') as $node) {
// your conditions to find out the id
$id = $node->getAttribute('id');
}
$dom = new DOMDocument();
$dom->load('2.xml');
$xpath = new DOMXPath($dom);
$element = $xpath->query("//*[#id='".$id."']")->item(0);
// would echo "top_2" based on my example files
echo $element->getAttribute('name');
Based on following test files:
1.xml
<?xml version="1.0" encoding="UTF-8"?>
<articles>
<article id="foo_1">
<title>abc</title>
</article>
<article id="foo_2">
<title>def</title>
</article>
</articles>
2.xml
<?xml version="1.0" encoding="UTF-8"?>
<tests>
<test id="foo_1" name="top_1">
</test>
<test id="foo_2" name="top_2">
</test>
</tests>
Use SimpleXML to create an object representation of the file. You can then loop through the elements of the Simple XML object.
Depending on the format of the XML file:
Assuming it is:
<xml>
<roomTypeCode>
<stuff>stuff</stuff>
<name>Skunkman</name>
</roomTypeCode>
<roomTypeCode>
<stuff>other stuff</stuff>
<name>Someone Else</name>
</roomTypeCode>
</xml>
It would be something like this:
$xml = simplexml_load_file('xmlfile.xml');
for($i = 0; $i < count($xml->roomTypeCode); $i++)
{
if($xml->roomTypeCode[$i]->stuff == "stuff")
{
$name = $xml->roomTypeCode[$i]->name;
}
}
That connects to the XML file, finds how many roomTypeCode entries there are, searches for the value of "stuff" within and when it matches it correctly, you can access anything having to do with that XML entry.
I was tesing with a simple example of how to display XML in browser using PHP and found this example which works good
<?php
$xml = new DOMDocument("1.0");
$root = $xml->createElement("data");
$xml->appendChild($root);
$id = $xml->createElement("id");
$idText = $xml->createTextNode('1');
$id->appendChild($idText);
$title = $xml->createElement("title");
$titleText = $xml->createTextNode('Valid');
$title->appendChild($titleText);
$book = $xml->createElement("book");
$book->appendChild($id);
$book->appendChild($title);
$root->appendChild($book);
$xml->formatOutput = true;
echo "<xmp>". $xml->saveXML() ."</xmp>";
$xml->save("mybooks.xml") or die("Error");
?>
It produces the following output:
<?xml version="1.0"?>
<data>
<book>
<id>1</id>
<title>Valid</title>
</book>
</data>
Now I have got two questions regarding how the output should look like.
The first line in the xml file '', should not be displayed, that is it should be hidden
How can I display the TextNode in the next line. In total I am exepecting an output in this fashion
<data>
<book>
<id>1</id>
<title>
Valid
</title>
</book>
</data>
Is that possible to get the desired output, if so how can I accomplish that.
Thanks
To skip the XML declaration you can use the result of saveXML on the root node:
$xml_content = $xml->saveXML($root);
file_put_contents("mybooks.xml", $xml_content) or die("cannot save XML");
Please note that saveXML(node) has a different output from saveXML().
First question:
here is my post where all usable threads with answers are listed: How do you exclude the XML prolog from output?
Second question:
I don't know of any PHP function that outputs text nodes like that.
You could:
read xml using DomDocument and save each node as string
iterate trough nodes
detect text nodes and add new lines to xml string manually
At the end you would have the same XML with text node values in new line:
<node>
some text data
</node>
I've created an XML document.
So, now, I want to find the good node and set the values of this node, but after any research about this topic, I don't know how to do it.
This is my document :
<?xml version="1.0" encoding="utf-8"?>
<scripts>
<script nom="myTools.class.php">
<titre>Useful php classes</titre>
<date>18/07/2011</date>
<options>
<option name="topic">Tutorials</option>
<option name="desc">Tutorial for you</option>
</options>
</script>
<script nom="index.php">
<titre>blabla</titre>
<date>15/07/2011</date>
<options>
<option name="topic">The homepage</option>
</options>
</script>
</scripts
>
So, I would to build an html form with theses values, but at this moment, I can't get and set that I want :(
I want get the first "script" node :
<script nom="myTools.class.php"> //How to set the "nom" attribute ?
<titre>Useful php classes</titre> //How to get this value and set it ?
<date>18/07/2011</date>
<options>
<option name="topic">Tutorials</option>
<option name="desc">Tutorial for you</option>
</options>
</script>
I have no problem to loop all the document, but not with only my "own choices"
Have you an idea ?
use XPath
first get the dom document
$dom=new DOMDocument();
$dom->loadXML('file'); // file is the name of XML file if u have a string of XML called $string then use $dom->loadXML($string)
$xpath=new DOMXPath($dom);
$path='//scripts/script[1]'; // that would get the first node
$elem=$xpath->query($path);
now $elem[0] is your first script node
if u want to get elements by their attribute then use $path='//scripts/script[#nom='attribute value']';
now using this path will return a nodeset with script elements having a nom attribute of ur given value
you can see more here
in response to bahamut100's comment
the xpath fot the option element is //options/option
now if u meant getting an option node by attribute value then do this
$path='//options/option[#attrib_name=attrib_value]';
$elem=$xpath->query($path);
but if u meant getting the attributes of a node then first u have to reach that node. in ur case u have to reach to the option node first
$path='//options/option';
$option=$xpath->query($path);
now $option is a node list
so for getting the first element's attibutes use
$attribute=$option[0]->attributes;
now $attribute is a NamedNodeMap so for getting the value of first attribute use
$value=$attribute->item(0);
XPath is one way of doing it:
$dom = new DOMDocument();
$dom->loadXML(... your xml here ...);
$xp = new DOMXPath($dom);
$results = $xp->query('//script[#nom='myTools.class.php']/titre');
$old_title = $results[0]->nodeValue;
$results[0]->nodeValue = 'New title here';