Generating XML from XPath - php

I have an example where I need to update an XML node based on an XPath. SimpleXMLElement makes this easy enough by using an XPath to grab the node and then update its value in a pass-by-reference format.
However, this doesn't work at all if the node doesn't actually exist that needs to be updated. Are there any simple ways to automatically generate the XML that matches the XPath if it doesn't exist?
An example:
<example>
<childNode1>green</childNode1>
</example>
Given the XML, I could easily run the xpath command to get the <childNode1> by loading up the xml into a SimpleXMLElement and then running $xml->xpath("example/childNode1");. I could then set the value of the returned SimpleXMLElement to something new and then save the xml.
However, if I needed to set something like <childNode2> the $xml->xpath("example/childNode2") would return nothing and it wouldn't be possible to set the value or confirm that the XML was built.
Is iterating through the XPath and parsing its values the only way to confirm that each child node exists and then build them out as it goes or is there a better way to generate the necessary XPath?

XPath is a query language used for selecting nodes in an XML structure and optionally computing values based on the contents of the XML. It does not possess functions that enable the editing of the XML or automagic node creation.
PHP's SimpleXML and DOM both have XPath implementations and allow the creation or updating of XML structures; I assume you know about them since you talk about editing nodes (I can give examples if you don't). To perform the kind of node additions that you are proposing, you would need to ascertain whether the node existed (e.g. if the xpath query for example/node1 returned a node, but example/node2 returned nothing), create a new node, and add it to the XML tree. For long xpaths, e.g. example/apple/blueberry/canola/date/emblem/node1, you would indeed have to parse the path and check which elements did exist, and add those that did not.
XQuery, a more powerful, fully-featured XML query language of which XPath 2 and XPath are part, will have the ability to transform XML. XQuery is in active development, but unfortunately the current implementations (as of late 2014) lack the ability to update XML. Watch this space though!

Related

PHP XML DOM looping through complex xml records with varying levels

I'm completely unfamiliar with PHP XML DOM, Any help appreciated.
I've been using the site and going through previous answers on this, and anywhere else I could find online, but I can't seem to find a good PHP XML DOM tutorial, my ultimate aim is to take a complex XML and use PHP to upload this into a mysql db. Can anyone recommend a good PHP XML DOM tutorial to do this?
I want to take all the child elements from an XML and put them into an associative array. So in the below 'entry' XML record it would get as far as 'ent_seq' realise there are no sub-nodes, and assign that to a value $array = ($ent_seq[$counter]=>1636730), then the loop would realise the next node is and realise this has subnodes, and choose to assign these subnodes as $array = ($ent_seq[$counter]=>1636730, $keb[$counter]=>通い, $ke_pri[$counter]=>news1); and continue on like that, breaking out the subnodes as appropriate.
<entry>
<ent_seq>1636730</ent_seq>
<k_ele>
<keb>通い</keb>
<ke_pri>news1</ke_pri>
<ke_pri>nf13</ke_pri>
</k_ele>
<r_ele>
<reb>かよい</reb>
<re_pri>news1</re_pri>
<re_pri>nf13</re_pri>
</r_ele>
<sense>
<pos>&n;</pos>
<gloss>coming and going</gloss>
<gloss>commuting</gloss>
</sense>
</entry>
I've not included any of the code I've come up with as its not helpful and it just selects the nodes at the ent_seq level, so for each record its only storing a few pieces of data, and all of the subnodes within the same record.
If anyone could point me in the right direction It would be appreciated.

putting xml elements in correct order for validation using php

I make modifications to an XML object using SimpleXML library and output it. But, order of the elements or attributes are not correct in the output and it does not validate with the schema.
Is there way to change order of the elements to be valid with xml schema ?
There's no way to re-order nodes using SimpleXML that I know of. Your best option may be to convert it to a DOMDocument object and then use the DOMNode->insertBefore() method to insert a new DOMNode before another one.
A good example of what you're looking to do may be http://us.php.net/manual/en/function.dom-import-simplexml.php.
source: Reorder XML nodes with php and simplexml

Storing / retrieving parts of an xml document with mysql, php, and simpleXML

I'm taking an xml document down from a partner API and I'd like to store the separate nodes into a mysql database so I can rebuild it with specific nodes. I absolutely do not want to parse out the complete document into the database as all I care about are the IDs and the individual nodes in total.
So for example:
<list>
<child>20-30 grandchildren</child>
<child></child>
<child></child>
...
<child></child>
</list>
I'd like to be able to put the blocks into a mysql database and then restore them. That's where I'm falling down: I use simple_xml to get the node and I use REPLACE to add it as a text, but I'm not sure how to them restore it back to . For an array, I'd serialize and than unserialize but that fails here.
Is there an obvious method I'm missing?
You serialize SimpleXMLElement objects to XML with asXML() then you can load the document normally with simplexml_load_string()
You cannot serialize SimpleXMLElement with serialize(), it will not work as expected.

How to parse an XML tree with DOMDocument?

Here is my XML file :
<?xml version="1.0" encoding="utf-8"?>
<root>
<category>
<name>Category</name>
<desc>Category</desc>
<category>
<name>Subcategory</name>
<desc>Sub-category</desc>
<category>
<name>Subcategory</name>
<desc>Sub-category</desc>
</category>
</category>
</category>
</root>
My tree could have as much levels as possible. There are no requirements about this.
First question :
Is my XML correct to handle this kind of requirement ?
and How could i optimize it (if it's needed)
Second question :
How could I parse it with DOMDocument ?
I know how to load an xml document, but I don't know how to parse it.
I read a little on recursion but I was not able to understand properly how to map with PHP/DOMDocument.
Thanks for the help !
EDIT
What I want to do is manage a category system.
I tried with SQL but it was too hard to manage using the relational model, even with nested select, etc...
So i want to be able make a tree from my xml
like
Category
Sub Category
Sub sub category
Without limits on the depth
I want to be able to search for a category, retrieve all its children (subcategories) (or not), its parent(s) (or not), (the sisters ?), etc...
Well, there's nothing wrong with the XML you're using here, but you don't say enough about what you want to DO with the data for anyone to give you a quality answer about whether or not your XML will capture what you need. As for "[parsing] it with DOMDocument", you can load it into a DOMDocument object like so:
$xml = <<<XML
<?xml version="1.0" encoding="utf-8"?>
<root>
<category>
<name>Category</name>
<desc>Category</desc>
<category>
<name>Subcategory</name>
<desc>Sub-category</desc>
<category>
<name>Subcategory</name>
<desc>Sub-category</desc>
</category>
</category>
</category>
</root>
XML;
$d = new DOMDocument();
$d->loadXML($xml);
At this point, the question once again becomes: Now what do you want to DO with it?
If you're just talking about how to handle a structure like this - i'd say write two functions, one that accepts the full structure, and one that accepts a category DOMNode reference. The first function would do initial processing then pass the first reference to the initial Category node. Then in this function, you process the current node's properties as needed, and then recurse into children if they are present.
It would be more efficient to process this flat of course, in one loop, but then you would lose the literal representation of the hierarchy.
Recapping the point above about what you want to do with it... IMHO there are three broad classes of thing one might do with a chunk of XML.
Having instantiated a DOMDocument and loaded XML into it, you can search it for nodes using XPath queries, much like you search a relational database using SQL SELECT queries. You can extract properties of node, sub-nodes of nodes and the text within nodes. Which is a species of parsing, I'd say. DOMDocument XPath component will do this for you.
You can instead maybe turn your XML into something else - different XML dialect, XHTML, etc, using XSL Transforms. Which may or may not be parsing per se, but does involve parsing. PHP XSLTProcessor component will do this.
Another major idea, which I think DOMDocument does not really support, is a streaming parser. The parser consumes XML in a linear manner, and while doing so invokes callback functions at each node of interest. The somewhat venerable parser named SAX is AFAIK the archetypal streaming parser. There used to be a SAX parser in PHP, I think it has now been moved to PEAR or PECL.
But, yeah, what do you want to do with your XML?
You said you tried SQL and it didn't work for you. Just a tip: If you use Oracle, take a look at START WITH ... CONNECT BY, if you use SQL Server, use recursive CTEs. These approaches do solve the problem.

Generating XML based on condition in PHP

Is it possible to generate XML based on condition. I am getting the XML output from Database, but i want to display the nodes in such a manner based on the ID.
If id of the elements are same, they should come under one node.
Have you checked out PHP's SimpleXML? It enables you to perform XPath queries on XML data
you can handle an xml in many ways and yes you can group the xml items per db id.
imho your question needs more details:
how do you get the xml?
how do you query the database?

Categories