XML count elements, if id there is an increment of one

What I'm trying to do is count the elements under the root element. Then check if one identifier at the same level has an id value. When this happens, it should increase by one.

Code

public function _generate_id() { $id = 0; $xpath = new DOMXPath($this->_dom); do{ $id++; } while($xpath->query("/*/*[@id=$id]")); return $id; } 

xml example

 <?xml version="1.0"?> <catalog> <book id="0"> <author>Gambardella, Matthew</author> <title>XML Developer Guide</title> <genre>Computer</genre> <price>44.95</price> <publish_date>2000-10-01</publish_date> <description>An in-depth look at creating applications with XML.</description> </book> <book id="1"> <author>Ralls, Kim</author> <title>Midnight Rain</title> <genre>Fantasy</genre> <price>5.95</price> <publish_date>2000-12-16</publish_date> <description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</description> </book> </catalog> 
+4
source share
3 answers

You can use the following xpath request to get the maximum id attribute value:

 $result = $xpath->query('/*/*[not(../*/@id > @id)]/@id'); 

In your function, you can return this value incremented by 1 :

 return intval($result->item(0)->nodeValue) + 1; 

Update. You can also perform the zoom operation using XPath. Note DOMXPath::evaluate() :

 return $xpath->evaluate('/*/*[not(../*/@id > @id)]/@id + 1'); |------- +1 in xpath 

This will give you 2 - but as a double. I would suggest converting to an integer before returning the result:

 return (integer) $xpath->evaluate('/*/*[not(../*/@id > @id)]/@id + 1'); 
+2
source

I suggest first creating an array of all existing identifier values ​​(which is a single xpath request), and then you check it:

 $id = 0; while(isset($ids[$id])) { $id++; } echo $id; # 2 

Creating such a list trivially launches xpath on SimpleXML, however it can be easily ported to DOMXPath, as well as using iterator_to_array :

 <?php $buffer = <<<BUFFER <?xml version="1.0"?> <catalog> <book id="0"> <author>Gambardella, Matthew</author> <title>XML Developer Guide</title> <genre>Computer</genre> <price>44.95</price> <publish_date>2000-10-01</publish_date> <description>An in-depth look at creating applications with XML.</description> </book> <book id="1"> <author>Ralls, Kim</author> <title>Midnight Rain</title> <genre>Fantasy</genre> <price>5.95</price> <publish_date>2000-12-16</publish_date> <description>A former architect battles corporate zombies, an evil sorceress, and her own childhood to become queen of the world.</description> </book> </catalog> BUFFER; $xml = simplexml_load_string($buffer); $ids = array_flip(array_map('intval', $xml->xpath("/*/*/@id"))); 

Interactive demo

In addition, I suggest you not use 0 (zero) as the ID value.

+1
source

Use simplexml, try

 $xml = simplexml_load_string($this->_dom); $id = is_array($xml->book) ? $xml->book[count($xml->book)-1]->attributes()->id : 0; return $id; 
+1
source

Source: https://habr.com/ru/post/1481632/


All Articles