Xml error This page contains the following errors: - php

php code creates xml and displays on screen. Unfortunately, I get an error and I don't know how to fix it.
This page contains the following errors:
error on line 2 at column 1: Extra content at the end of the document
Below is a rendering of the page up to the first error.
The structure of the xml file itself looks good after saving
<Movies>
<movie movie_id="5467">
<Title>The Campaign</Title>
<Year>2012</Year>
<Genre>The Campaign</Genre>
<Ratings>6.2</Ratings>
</movie>
</Movies>
I need to display the same code on screen after calling php.
$dom = new DOMDocument();
$dom->encoding = 'utf-8';
$dom->xmlVersion = '1.0';
$dom->formatOutput = true;
$xml_file_name = 'movies_list.xml';
$root = $dom->createElement('Movies');
$movie_node = $dom->createElement('movie');
$attr_movie_id = new DOMAttr('movie_id', '5467');
$movie_node->setAttributeNode($attr_movie_id);
$child_node_title = $dom->createElement('Title', '<![CDATA[The Campaign]]');
$movie_node->appendChild($child_node_title);
$child_node_year = $dom->createElement('Year', 2012);
$movie_node->appendChild($child_node_year);
$child_node_genre = $dom->createElement('Genre', '<![CDATA[The Campaign]]');
$movie_node->appendChild($child_node_genre);
$child_node_ratings = $dom->createElement('Ratings', 6.2);
$movie_node->appendChild($child_node_ratings);
$root->appendChild($movie_node);
$dom->appendChild($root);
Header('Content-type: text/xml');
echo $xml_file_name->asXML();
Please help me in solving. I looked for many solutions but nothing helped.

Related

How to update Document-A XML nodes with Document-B XML nodes using php

I have two XML files: one from a client and one created from a db query. The db XML file has this structure:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<metadata xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<tags>
<title>Wordsleuth (2006, volume 3, 4): The Dictionary: Disapproving Schoolmarm or Accurate Record?</title>
<alias>favart/wordsleuth-2006-volume-3-4-the-dictionary-disapproving-schoolmarm-or-accurate-record</alias>
<id>4361</id>
</tags>
</metadata>
The client XML has this structure:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<metadata xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<tags>
<title>Wordsleuth (2006, vol. 3, 4): The Dictionary: Disapproving Schoolmarm or Accurate Record? – Search by Title – Favourite Articles – TERMIUM Plus® – Translation Bureau</title>
<description>A Language Update article on the role that the dictionary plays in language usage.</description>
<keywords>language usage; dictionaries</keywords>
<subject>English language; Terminology</subject>
</tags>
</metadata>
Each with approx 200 'tags' elements. After getting some hints from here and here and referencing the PHP manual my first crack at it produced this:
$client = 'C:\xampp\htdocs\wetkit\sites\all\modules\my_metatags\favart.xml';
$db = 'C:\xampp\htdocs\wetkit\sites\all\modules\my_metatags\tmp\from db\favart_db.xml';
$c_xmlstr = file_get_contents($client);
$d_xmlstr = file_get_contents($db);
$favartdoc_db = new DomDocument('1.0','UTF-8');
$favartdoc_cl = new DomDocument('1.0','UTF-8');
$favartdoc_db->loadXML($d_xmlstr);
$favartdoc_cl->loadXML($c_xmlstr);
for ($i=0;$i==$favartdoc_cl->getElementsByTagName('title')->count; $i++){
$c_nodes = $x_favartdoc_cl->query('/metadata/tags/title');
$c_node = $c_nodes->item($i);
for ($j=0; $j==$favartdoc_db->getElementsByTagName('title')->count; $j++){
$d_nodes = $x_favartdoc_db->query('/metadata/tags/title');
$d_node = $d_nodes->item($j);
if(stripos(trim($c_node->nodeValue), trim($d_node->nodeValue))===0){
$favartdoc_cl->replaceChild($d_node,$c_node);
if($i==($c_nodes->count)){break;};
}
}
$favartdoc_cl->saveXML();
}
This code runs, generates no errors, and does nothing. An echo statement at the end
echo "\n\n" . "THE TOTAL NUMBER OF MATCHES EQUALS " . $i . " IN " . $j . " NODES." . "\n";
generates this message:
THE TOTAL NUMBER OF MATCHES EQUALS 1 IN 1 NODES.
A second simpler approach produced this:
$favartdoc_db = new DomDocument('1.0','UTF-8');
$favartdoc_cl = new DomDocument('1.0','UTF-8');
$favartdoc_db->load($db);
$favartdoc_cl->load($client);
$favartdoc_cl->formatOutput = true;
$c_meta_x = new DOMXpath($favartdoc_cl);
$d_meta_x = new DOMXpath($favartdoc_db);
foreach ($c_meta_x->query('//tags') as $c_tag){
foreach ($d_meta_x->query('//tags') as $d_tag){
if(strncasecmp(trim($c_tag->title), trim($d_tag->title) , strlen(trim($d_tag->title)))===0){
$c_tag->appendChild($d_tag);
}
}
}
$favartdoc_cl->saveXML();
But this generates an error:
exception 'DOMException' with message 'Wrong Document Error'
Suggestions to correct that error, by calling importNode before attaching it to the DOM, still generate the same error.
As you can see I'm trying a different string matching function in each. Ultimately I want to replace the titles in the client XML with those from the db or append the whole tag set from the db XML to the client XML then delete the client title element afterwards.
Any help would be appreciated.
This is what worked for me.
$client = 'some\where\somefile.xml';
$db = 'some\where\someOtherfile.xml';
$c_xmlstr = file_get_contents($client);
$d_xmlstr = file_get_contents($db);
$doc_db = new DomDocument('1.0','UTF-8');
$doc_cl = new DomDocument('1.0','UTF-8');
$doc_db->loadXML($d_xmlstr);
$fdoc_cl->loadXML($c_xmlstr);
$x_doc_db = new DOMXpath($doc_db);
$x_doc_cl = new DOMXpath($doc_cl);
$c_nodes = $x_doc_cl->query('/metadata/tags');
$c_nodes_titles = $x_doc_cl->query('/metadata/tags/title');
for($i=0;$i<=$c_nodes->length;++$i){
$c_node = $c_nodes->item($i);
$c_node_title = $c_nodes_titles->item($i);
$d_nodes = $x_doc_db->query('/metadata/tags');
$d_nodes_titles = $x_doc_db->query('/metadata/tags/title');
$d_nodes_ids = $x_doc_db->query('/metadata/tags/id');
for($j=0;$j<=$d_nodes->length;++$j){
$d_node_title = $d_nodes_titles->item($j);
$d_node_id = $d_nodes_ids->item($j);
if(strncasecmp(trim($c_node_title->textContent),trim($d_node_title->textContent) , strlen(trim($d_node_title->textContent)))===0 && trim($c_node_title->textContent)===trim($d_node_title->textContent)){
$db_id = $doc_cl->createElement("db_id");
$db_id_val = $doc_cl->createTextNode($d_node_id->nodeValue);
if(!is_null($c_node)){$c_node->appendChild($db_id);}
if(!is_null($c_node)){$c_node->appendChild($db_id_val);}
}
}
if($i===($c_nodes->count) && $j===($d_nodes->count)){break;};
}
$doc_cl->saveXML();

domDocument's formatOutput property writes inline [duplicate]

Here are the codes:
$doc = new DomDocument('1.0');
// create root node
$root = $doc->createElement('root');
$root = $doc->appendChild($root);
$signed_values = array('a' => 'eee', 'b' => 'sd', 'c' => 'df');
// process one row at a time
foreach ($signed_values as $key => $val) {
// add node for each row
$occ = $doc->createElement('error');
$occ = $root->appendChild($occ);
// add a child node for each field
foreach ($signed_values as $fieldname => $fieldvalue) {
$child = $doc->createElement($fieldname);
$child = $occ->appendChild($child);
$value = $doc->createTextNode($fieldvalue);
$value = $child->appendChild($value);
}
}
// get completed xml document
$xml_string = $doc->saveXML() ;
echo $xml_string;
If I print it in the browser I don't get nice XML structure like
<xml> \n tab <child> etc.
I just get
<xml><child>ee</child></xml>
And I want to be utf-8
How is this all possible to do?
You can try to do this:
...
// get completed xml document
$doc->preserveWhiteSpace = false;
$doc->formatOutput = true;
$xml_string = $doc->saveXML();
echo $xml_string;
You can make set these parameter right after you've created the DOMDocument as well:
$doc = new DomDocument('1.0');
$doc->preserveWhiteSpace = false;
$doc->formatOutput = true;
That's probably more concise. Output in both cases is (Demo):
<?xml version="1.0"?>
<root>
<error>
<a>eee</a>
<b>sd</b>
<c>df</c>
</error>
<error>
<a>eee</a>
<b>sd</b>
<c>df</c>
</error>
<error>
<a>eee</a>
<b>sd</b>
<c>df</c>
</error>
</root>
I'm not aware how to change the indentation character(s) with DOMDocument. You could post-process the XML with a line-by-line regular-expression based replacing (e.g. with preg_replace):
$xml_string = preg_replace('/(?:^|\G) /um', "\t", $xml_string);
Alternatively, there is the tidy extension with tidy_repair_string which can pretty print XML data as well. It's possible to specify indentation levels with it, however tidy will never output tabs.
tidy_repair_string($xml_string, ['input-xml'=> 1, 'indent' => 1, 'wrap' => 0]);
With a SimpleXml object, you can simply
$domxml = new DOMDocument('1.0');
$domxml->preserveWhiteSpace = false;
$domxml->formatOutput = true;
/* #var $xml SimpleXMLElement */
$domxml->loadXML($xml->asXML());
$domxml->save($newfile);
$xml is your simplexml object
So then you simpleXml can be saved as a new file specified by $newfile
<?php
$xml = $argv[1];
$dom = new DOMDocument();
// Initial block (must before load xml string)
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
// End initial block
$dom->loadXML($xml);
$out = $dom->saveXML();
print_R($out);
Tried all the answers but none worked. Maybe it's because I'm appending and removing childs before saving the XML.
After a lot of googling found this comment in the php documentation. I only had to reload the resulting XML to make it work.
$outXML = $xml->saveXML();
$xml = new DOMDocument();
$xml->preserveWhiteSpace = false;
$xml->formatOutput = true;
$xml->loadXML($outXML);
$outXML = $xml->saveXML();
// ##### IN SUMMARY #####
$xmlFilepath = 'test.xml';
echoFormattedXML($xmlFilepath);
/*
* echo xml in source format
*/
function echoFormattedXML($xmlFilepath) {
header('Content-Type: text/xml'); // to show source, not execute the xml
echo formatXML($xmlFilepath); // format the xml to make it readable
} // echoFormattedXML
/*
* format xml so it can be easily read but will use more disk space
*/
function formatXML($xmlFilepath) {
$loadxml = simplexml_load_file($xmlFilepath);
$dom = new DOMDocument('1.0');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($loadxml->asXML());
$formatxml = new SimpleXMLElement($dom->saveXML());
//$formatxml->saveXML("testF.xml"); // save as file
return $formatxml->saveXML();
} // formatXML
Two different issues here:
Set the formatOutput and preserveWhiteSpace attributes to TRUE to generate formatted XML:
$doc->formatOutput = TRUE;
$doc->preserveWhiteSpace = TRUE;
Many web browsers (namely Internet Explorer and Firefox) format XML when they display it. Use either the View Source feature or a regular text editor to inspect the output.
See also xmlEncoding and encoding.
This is a slight variation of the above theme but I'm putting here in case others hit this and cannot make sense of it ...as I did.
When using saveXML(), preserveWhiteSpace in the target DOMdocument does not apply to imported nodes (as at PHP 5.6).
Consider the following code:
$dom = new DOMDocument(); //create a document
$dom->preserveWhiteSpace = false; //disable whitespace preservation
$dom->formatOutput = true; //pretty print output
$documentElement = $dom->createElement("Entry"); //create a node
$dom->appendChild ($documentElement); //append it
$message = new DOMDocument(); //create another document
$message->loadXML($messageXMLtext); //populate the new document from XML text
$node=$dom->importNode($message->documentElement,true); //import the new document content to a new node in the original document
$documentElement->appendChild($node); //append the new node to the document Element
$dom->saveXML($dom->documentElement); //print the original document
In this context, the $dom->saveXML(); statement will NOT pretty print the content imported from $message, but content originally in $dom will be pretty printed.
In order to achieve pretty printing for the entire $dom document, the line:
$message->preserveWhiteSpace = false;
must be included after the $message = new DOMDocument(); line - ie. the document/s from which the nodes are imported must also have preserveWhiteSpace = false.
based on the answer by #heavenevil
This function pretty prints using the browser
function prettyPrintXmlToBrowser(SimpleXMLElement $xml)
{
$domXml = new DOMDocument('1.0');
$domXml->preserveWhiteSpace = false;
$domXml->formatOutput = true;
$domXml->loadXML($xml->asXML());
$xmlString = $domXml->saveXML();
echo nl2br(str_replace(' ', ' ', htmlspecialchars($xmlString)));
}

How to append new elemnt to XML-file using php DOMdocument?

I have this test.xml:
<?xml version="1.0"?>
<Images>
<Image>
<Id>765</Id>
<Title>Img title 1</Title>
<Name>some_path_to_img.jpg</Name>
</Image>
</Images>
I try to append new '<Image>' to '<Images>', but without success.
Here is my code:
function update_xml_file() {
$xml = new DOMDocument();
$xml->load(file_get_contents('test.xml'));
$xml->formatOutput = true;
$base_node = $xml->getElementsByTagName('Images')->item(0);
$newimage = $xml->createElement("Image");
$img_id = $xml->createElement("Id");
$img_title = $xml->createElement("Title");
$img_name = $xml->createElement("Name");
$img_id->nodeValue = '766';
$img_title->nodeValue = 'Image title 2';
$img_name->nodeValue = 'some_path_to_img2.jpg';
$newimage->appendChild($img_id);
$newimage->appendChild($img_title);
$newimage->appendChild($img_name);
$base_node->appendChild($newimage);
umask();
$xml->save("test.xml");
}
Looking around for related discussions didn't help me.
Thanks for your time.
You have a little typo in the code which loads the xml data.
Change it to:
$xml->loadXML(file_get_contents('test.xml'));
or ( better)
$xml->load('test.xml');
Refer to the documentation of DOMDocument::loadXML() and DOMDocument::load()
You can also use this package from github to make it simple http://github.com/toureiliass/xdt
You can do it in a few line of code
$con = new XDT();
$con->connect('test.xml');
$con->getDocumentRootElement()->append('<image><id>765</id><title>some title</title><name>some_path_to_image.jpg</name></image>');
$con->save();

XML Encoding generated from PHP

I am doing an assignment for class where I have to use a Java Servlet running on Tomcat and have it message a php file to scrape IMDB for movie information and return it as XML to the servlet. It seems to not want to accept any encoding I give it as I continuously get XML tags such as the ones below.
<result cover="url" title="Pokémon" year="1998 TV Series" director="N/A" rating="7.8" details="http://www.imdb.com/title/tt0176385/"/>
Where title of Pokemon should have an accent over the e («é»). I have the following php code to generate the xml. (Important parts only)
<?php header("Content-Type: text/xml; charset=utf-8");
$xml = new DOMDocument();
$rsp = $xml->appendChild($xml->createElement("rsp"));
$xml->encoding = 'utf-8';
$titleNames[$i] = utf8_encode($title_tmp[1]);
$results = $rsp->appendChild($xml->createElement("results"));
$results->setAttribute("total", $tableRows);
$item->setAttribute("title", $titleNames[$i]);
echo $xml->saveXML();
?>
Any help would be greatly appreciated in figuring out how to correctly display special characters!
It's impossible to say what's wrong from your code fragments (which don't even run) but $xml->encoding = 'utf-8' should work. Please compare:
$xml = new DOMDocument();
$rsp = $xml->appendChild($xml->createElement("rsp"));
$rsp->setAttribute("title", 'Pokémon');
echo $xml->saveXML();
/*
<?xml version="1.0"?>
<rsp title="Pokémon"/>
*/
... with:
$xml = new DOMDocument();
$xml->encoding = 'utf-8';
$rsp = $xml->appendChild($xml->createElement("rsp"));
$rsp->setAttribute("title", 'Pokémon');
echo $xml->saveXML();
/*
<?xml version="1.0" encoding="utf-8"?>
<rsp title="Pokémon"/>
*/
(These snippets are expected to be saved as UTF-8).

XML Parsing Error

here i am creating xml file dynamically at run time but i m getting error
XML Parsing Error: junk after document element
Location: http://localhost/tam/imagedata.php?imageid=8
Line Number 9, Column 1:
^
$id=$_GET['imageid'];
$dom = new DomDocument('1.0');
$query="select * from tbl_image_gallery where imageId='$id'";
$select=mysql_query($query);
while($res=mysql_fetch_array($select))
{
$content = $dom->appendChild($dom->createElement('content'));
$image = $content->appendChild($dom->createElement('image'));
$small_image_path = $image->appendChild($dom->createElement('small_image_path'));
$small_image_path->appendChild($dom->createTextNode("load/images/small/".$res['image']));
$big_image_path = $image->appendChild($dom->createElement('big_image_path'));
$big_image_path->appendChild($dom->createTextNode("load/images/big/".$res['image']));
$description = $image->appendChild($dom->createElement('description'));
$description->appendChild($dom->createTextNode($res['description']));
$dom->formatOutput = true;
}
echo $test1 = $dom->saveXML();
and xml format is
<?xml version="1.0"?>
<content>
<image>
<small_image_path>load/images/small/1.jpg</small_image_path>
<big_image_path>load/images/big/1.jpg</big_image_path>
<description>hgjghj</description>
</image>
<image><small_image_path>load/images/small/2.jpg</small_image_path><big_image_path>load/images/big/2.jpg</big_image_path><description>fgsdfg</description></image><image><small_image_path>load/images/small/3.jpg</small_image_path><big_image_path>load/images/big/3.jpg</big_image_path><description>sdfgsdfg</description></image><image><small_image_path>load/images/small/4.jpg</small_image_path><big_image_path>load/images/big/4.jpg</big_image_path><description>gsbhsg</description></image><image><small_image_path>load/images/small/4.jpg</small_image_path><big_image_path>load/images/big/4.jpg</big_image_path><description>gsbhsg</description></image><image><small_image_path>load/images/small/avatar.jpg</small_image_path><big_image_path>load/images/big/avatar.jpg</big_image_path><description></description></image></content>
Can it be that you are posting html code into the description field?
Could be usefull to add a CDataSection instead of a TextNode
$cdata = $dom->createCDATASection($res['description']);
$image->appendChild($cdata);

Categories