PHP reading XML with Where Clause - php

Let's say I have this XML file.
<book>
<id>1</id>
<title>Harry Potter - bla bla bla</title>
<author>J.K Rowling</author>
</book>
<book>
<id>2</id>
<title>Other book</title>
<author>A Name</author>
</book>
Is there a way where I can read via PHP and get the #2 id, or do I have to use an IF?
Like jQuery selector ':eq(2)', or MySql 'WHERE id=2'

There is, try SimpleXML parser of php: http://php.net/manual/en/book.simplexml.php

If all you want is just the second one you can use DOM. It's simpler.
$dom->loadXML(<<<XML
<book>
<id>1</id>
<title>Harry Potter - bla bla bla</title>
<author>J.K Rowling</author>
</book>
<book>
<id>2</id>
<title>Other book</title>
<author>A Name</author>
</book>
XML;);
$book=$dom->getElementsByTagName('book')->item(1);
Edit: I just saw you say you were looking for second ID, not second element, you need xpath for that.
$xml=new SimpleXMLElement(<<<XML
<book>
<id>1</id>
<title>Harry Potter - bla bla bla</title>
<author>J.K Rowling</author>
</book>
<book>
<id>2</id>
<title>Other book</title>
<author>A Name</author>
</book>
XML;);
$result=$xml->xpath('/book[id=2]');
More on xpath here

Related

Getting Parent Node from XML file into a String in PHP

So, I'm parsing data from an XML feed in to php variables and everything is fine with the exception of the "link" element. It's not in a child like the others.
A cleaner, simpler example of the structure is below:
<bookstore>
<book category="children">
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
<link href="http://example.com">
</book>
<book category="web">
<title>Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
<link href="http://example.com">
</book>
</bookstore>
<bookstore>
<book category="children">
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price>29.99</price>
<link href="http://example.com">
</book>
<book category="web">
<title>Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
<link href="http://example.com">
</book>
</bookstore>
How do I read the link/href part of the XML in the parent node /bookstore/ and put it in to a string? It looks like it's been badly formatted, but I can't change it as it's supplied by a third party.
I thought I could load the entire /bookstore/ parent and search through it for the link and pull the value that way but it won't load the entire bookstore element.
My code is also extracting the other child tags fine and running through a loop to show the data in a list. Any help would be appreciated.
Edit: This is the link to the XML file I have to use: https://www.reddit.com/r/elderscrollsonline.xml
For SimpleXML - this code:
$rss = 'some_url_here';
$xml = simplexml_load_file($rss);
For you xml:
foreach($xml->bookstore as $bookstore) {
foreach ($bookastore as $book)
echo (string)$book->link['href'];
}
For links in https://www.reddit.com/r/elderscrollsonline.xml:
foreach($xml->entry as $book) echo (string)$book->link['href'];

How to get value of xml element

I need to retrieve the value of the value of "TotalBooks" from an xml file that is structured like the example below.
I can get the equivalent of the "MatchesFound" value by doing a count of "book" and I can successfully get the information for each book.
However, I cannot get the actual value shown in the xml file for "MatchesFound", "TotalBooks", and "Page".
I'm using php with simplexml_load_file. Any help I can get is appreciated. Thanks.
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<MatchesFound>2</MatchesFound>
<TotalBooks>563</TotalBooks>
<Page>1</Page>
<book>
<title>Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price currency="USD">30.00</price>
</book>
<book>
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price currency="USD">29.99</price>
</book>
</bookstore>
$xml = new SimpleXMLElement($xmlString);
echo $xml->TotalBooks;
Using xpath :
<?php
$string = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<MatchesFound>2</MatchesFound>
<TotalBooks>563</TotalBooks>
<Page>1</Page>
<book>
<title>Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price currency="USD">30.00</price>
</book>
<book>
<title>Harry Potter</title>
<author>J K. Rowling</author>
<year>2005</year>
<price currency="USD">29.99</price>
</book>
</bookstore>
XML;
$xml = new SimpleXMLElement($string);
$result = $xml->xpath('//TotalBooks');
while(list( , $node) = each($result)) {
echo "$node\n";
}
?>
See http://php.net/manual/en/simplexmlelement.xpath.php

cloneNode + appendChild + insertBefore dom xml php

I have an xml and I would be cloning father and leave under the cloned node.
More giving this error.
I wonder how
Fatal error: Call to a member function insertBefore() on a non-object in C:\xampp\htdocs\xml2\cloneNew.php on line 32
$xmla = <<<XML
<?xml version="1.0" ?>
<library>
<book isbn="1001" pubdate="1943-01-01">
<title><![CDATA[The Fountainhead]]></title>
<author>Ayn Rand</author>
<price>300</price>
</book>
<book isbn="1002" pubdate="1954-01-01">
<title><![CDATA[The Lord of the Rings]]></title>
<author>J.R.R.Tolkein</author>
<price>500</price>
</book>
<book isbn="1006" pubdate="1982-01-01">
<title><![CDATA[The Dark - Tower San]]></title>
<author>Stephen King</author>
<price>200</price>
</book>
</library>
XML;
$xmlb = <<<XML
<?xml version="1.0" ?>
<library>
<book isbn="1004" pubdate="1943-01-01">
<title><![CDATA[The Fountainhead]]></title>
<author>Ayn Rand</author>
<price>300</price>
</book>
</library>
XML;
$dom_01 = new DOMDocument();
$dom_01->loadXML($xmla);
$library_01 = $dom_01->documentElement;
$dom_02 = new DOMDocument();
$dom_02->loadXML($xmlb);
$library_02 = $dom_02->documentElement;
$xpath = new DOMXPath($dom_02);
$result = $xpath->query('/library/book[translate(#pubdate,"-","")>translate("1980-01-01","-","")]');
$library_02 = $library_02->cloneNode(true);
$newElement = $library_01->appendChild($result->item(0));
$library_01->parentNode->insertBefore($newElement, $result->item(0));
header("Content-type: text/xml");
echo $dom->saveXML();
Result:
$xmla = <<<XML
<?xml version="1.0" ?>
<library>
<book isbn="1001" pubdate="1943-01-01">
<title><![CDATA[The Fountainhead]]></title>
<author>Ayn Rand</author>
<price>300</price>
</book>
<book isbn="1002" pubdate="1954-01-01">
<title><![CDATA[The Lord of the Rings]]></title>
<author>J.R.R.Tolkein</author>
<price>500</price>
</book>
<book isbn="1004" pubdate="1943-01-01">
<title><![CDATA[The Fountainhead]]></title>
<author>Ayn Rand</author>
<price>300</price>
</book>
<book isbn="1006" pubdate="1982-01-01">
<title><![CDATA[The Dark - Tower San]]></title>
<author>Stephen King</author>
<price>200</price>
</book>
</library>
XML;
You are trying to get the parentNode of a documentElement no such node exists.
Also if you want to place a node from one document into another use DOMDocument.importNode instead of cloneNode.

PHP XML: How To Get The NodeValue by Its Siblings?

Example of the xml:
<books>
<book>
<title>Hip Hop Hippo</title>
<released>31-12-9999</released>
</book>
<book>
<title>Bee In A Jar</title>
<released>01-01-0001</released>
</book>
</books>
I want to make a function that return the released date of a book title.
Ex: I want to get released date of the 'Hip Hop Hippo' book.
I know I can use simplexml and write ->book[0]->released. But that's only works when I have a static XML and I know where the ->book[$i]->title that match 'Hip Hop Hippo'. But not in dynamic case. I can't predict every changes, since it came from an API provider. It can be book[1], book[2], and so on.
What should I write in my function?
Check out the xpath functions http://php.net/manual/en/simplexmlelement.xpath.php
You will then be able to write a query like: /books/book[title="Hip Hop Hippo"]
$string = <<<XML
<books>
<book>
<title>Hip Hop Hippo</title>
<released>31-12-9999</released>
</book>
<book>
<title>Hip Hop Hippo</title>
<released>31-12-2000</released>
</book>
<book>
<title>Bee In A Jar</title>
<released>01-01-0001</released>
</book>
</books>
XML;
$xml = new SimpleXMLElement($string);
$result = $xml->xpath('/books/book[title="Hip Hop Hippo"]');
foreach($result as $key=>$node)
{
echo '<li>';
echo $node->title . ' / ' . $node->released;
echo '</li>';
}

Renaming a DOMNode in PHP

<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<Document xmlns='urn:iso:std:iso:20022:tech:xsd:pain.001.001.02'>
<books>
<book>
<qty>12</qty>
<title>C++</title>
</book>
<book>
<qty>21</qty>
<title>PHP</title>
</book>
</books>
<books>
<book>
<qty>25</qty>
<title>Java</title>
</book>
<book>
<qty>32</qty>
<title>Python</title>
</book>
<book>
<qty>22</qty>
<title>History</title>
</book>
</books>
</Document>
How Can I Rename ?
<Document xmlns='urn:iso:std:iso:20022:tech:xsd:pain.001.001.02'>
TO
<Document>
here you don't rename, you remove an attribute. Maybe DomElement::removeAttribute (http://php.net/manual/en/domelement.removeattribute.php) will do the work BUT if he doesn't because xmlns defines a namespace try to redefine the default namespace to null.

Categories