cloneNode + appendChild + insertBefore dom xml php - 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.

Related

XPath - displaying attributes

I have a following script:
<?php
$str = '<?xml version="1.0" encoding="utf-8"?>
<ROOT>
<ITEMS>
<BOOK>
<TITLE>Name 1</TITLE>
<AUTHOR>Author</AUTHOR>
<CATEGORY id="1">NOVEL</CATEGORY>
</BOOK>
<BOOK>
<TITLE>Name 2</TITLE>
<AUTHOR>Author</AUTHOR>
<CATEGORY id="2">MANUAL</CATEGORY>
</BOOK>
</ITEMS>
</ROOT>';
$xml = simplexml_load_string($str);
$category = $xml->xpath("/ROOT/ITEMS/BOOK/CATEGORY/text()");
print_r($category);
?>
I want to select all the categiries in xpath.
I tried also:
$category = $xml->xpath("/ROOT/ITEMS/BOOK/CATEGORY");
But my output is:
Array ( [0] => SimpleXMLElement Object ( [#attributes] => Array ( [id] => 1 ) ) [1] => SimpleXMLElement Object ( [#attributes] => Array ( [id] => 2 ) ) )
I don't want this output. I want to display NOVEL and MANUAL. I don't understand it, because I didn't use attribute command in xpath and I got it.
How to solve it? Thank you.
I have own solution. After few hours I have it! Thanks to your link in your answer. I read the examples and found how to get the right values.
<?php
$str = '<?xml version="1.0" encoding="utf-8"?>
<ROOT>
<ITEMS>
<BOOK>
<TITLE>Name 1</TITLE>
<AUTHOR>Author</AUTHOR>
<CATEGORY id="1">NOVEL</CATEGORY>
</BOOK>
<BOOK>
<TITLE>Name 2</TITLE>
<AUTHOR>Author</AUTHOR>
<CATEGORY id="2">MANUAL</CATEGORY>
</BOOK>
</ITEMS>
</ROOT>';
$xml = simplexml_load_string($str);
$category = $xml->xpath("/ROOT/ITEMS/BOOK/CATEGORY/text()");
while(list( , $node) = each($category)) {
echo $node."<BR />";
}
?>
When you use xpath return arrays is an array of SimpleXMLElement Objects (http://php.net/manual/ru/simplexmlelement.xpath.php), so they have their own structures. Somehow, you can iterate over this array and get all node values like this:
<?php
$str = '<?xml version="1.0" encoding="utf-8"?>
<ROOT>
<ITEMS>
<BOOK>
<TITLE>Name 1</TITLE>
<AUTHOR>Author</AUTHOR>
<CATEGORY id="1">NOVEL</CATEGORY>
</BOOK>
<BOOK>
<TITLE>Name 2</TITLE>
<AUTHOR>Author</AUTHOR>
<CATEGORY id="2">MANUAL</CATEGORY>
</BOOK>
</ITEMS>
</ROOT>';
$xml = simplexml_load_string($str);
$categories = $xml->xpath("/ROOT/ITEMS/BOOK/CATEGORY/text()");
foreach($categories as $category) {
echo "$category\n";
}

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

PHP reading XML with Where Clause

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

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