views:

414

answers:

4

Hi,

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...

+1  A: 

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?

TML
+1  A: 

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.

sparkey0
A: 

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?

Eric M
edited my question
A: 

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.

erikkallen