I want to process a XML file In php - php

This is my XML file
<?xml version="1.0" encoding="UTF-8"?>
<searchresult>
<query>file</query>
<page-number>3</page-number>
<start>20</start>
<files-per-page>10</files-per-page>
<files-approx-count>6361998</files-approx-count>
<result-files>
<file>
<name>file 1</name>
<description>
descrp
</description>
<url>
http://www.example.com
</url>
</file>
<file>
<name>file 2</name>
<description>
descrp 2
</description>
<url>
http://www.example.com
</url>
</file>
</result-files>
</search-result>
i tried the following code
$xml = simplexml_load_file("file.xml");
foreach ($xml as $xmls):
$name =$xmls->name;
$url =$xmls->url;
echo $name.$url;
endforeach;
but no output please help.

First thing, your XML file is not well-formed. The root tag is <searchresult> while the last tag is </search-result>. This causes a parsing error.
Second thing, if your tags contain dashes, those tags cannot be used directly as variables with SimpleXML, in that case you should use a special syntax (see this: php simplexml_load_file with a dash ( - )). Other way to fix this is, if you control de XML syntax, change the way the XML is written and don't use dashes on tags.
Lastly, I think you want to print out the info of files within the result-files tag.
$xml = simplexml_load_file("file.xml");
foreach ($xml->{'result-files'}->file as $file) {
printFile($file);
}
function printFile($file) {
$name = trim($file->name);
$url = trim($file->url);
print "$name $url\n";
}
Output:
file 1 http://www.example.com
file 2 http://www.example.com
And you are done.

You're creating an object when you use the simplexml_load_file. The object isn't necessarily iterable - but it is indexable by tag names. try not doing the foreach(...) and instead just using echo $xml->name;. If that doesn't work, then perhaps you're looking in the wrong directory for your file. You likely need to do something like:
EDITED TO MATCH XML FILE PROVIDED
$path = $_SERVER['DOCUMENT_ROOT']."/file.xml";
$xml = simplexml_load_file($path);
echo $xml->start; //should output 20

Related

Getting a specific XML element value with PHP

I have an XML structure like this
<companies>
<company>
<vatno>12345678</vatno>
<name>
<founded>2013-12-31</founded>
<text>XYZ Inc</text>
</name>
<location>
<streetname>West Road</streetname>
<county>
<no>12345</no>
<text>East County</text>
<county>
</location>
</company>
</companies>
I am trying to get specific info from the elements into PHP variables.
To get "vatno" I use:
$vatno = $xmlObject->item($i)->getElementsByTagName('vatno')->item(0)->childNodes->item(0)->nodeValue;
But what if I need the county name for example?
I cannot use getElementsByTagName('text') as it would get the company name also using the element name "text".
You may be better off using SimpleXML, you can then access the various components in a more intuitive way.
The example above would be something like...
$data = <<< XML
<companies>
<company>
<vatno>12345678</vatno>
<name>
<founded>2013-12-31</founded>
<text>XYZ Inc</text>
</name>
<location>
<streetname>West Road</streetname>
<county>
<no>12345</no>
<text>East County</text>
</county>
</location>
</company>
</companies>
XML;
$xml = simplexml_load_string($data);
foreach ( $xml->company as $company ) {
echo $company->vatno.PHP_EOL;
echo $company->location->county->text.PHP_EOL;
}
So each sub element is accessed using ->.
If you wanted to stick with what you already had, you should be able to use...
$countyName = $xmlObject->item($i)->getElementsByTagName('text')->item(1)
->nodeValue;
Using item(1) will fetch the second instance of the <text> elements, so this assumes that the name will have this value as well.
It works with SimpleXML if I use
$xml = simplexml_load_string($data);
foreach ( $xml->companies->company as $company ) {
echo $company->vatno.PHP_EOL;
echo $company->location->county->text.PHP_EOL;
}

PHP - Delete last line from xml

I have this XML file called help_cat.xml
<?xml version="1.0" encoding="utf-8"?>
<ROOT>
</ROOT>
I want to do something like delete </ROOT> from the XML add new content and give </ROOT> back at the end of the XML file.
But I have the problem with the first step. Delete </ROOT>.
I tried
<?php
$file = "help_cat.xml";
$lines = file($file);
echo sizeof($lines)."<BR />";
$last = sizeof($lines)-1;
echo $lines[$last]."<BR />";
unset($lines[$last]);
?>
The script wrote well that there are 3 rows in the file, but can't delete last row. Could someone help me, please?

Parse XML to HTML with PHP SimpleXMLElement

I am having some issues with SimpleXMLElement that I was hoping to get some help.
I was reading about SimpleXMLElement and I built a PHP page to parse this XML:
<?xml version='1.0'?>
<AdXML>
<Response>
<Campaign>
<Overview>
<Name>strip</Name>
<Description>category</Description>
<Status>L</Status>
</Overview>
<Pages>
<Url>page01</Url>
<Url>page02</Url>
<Url>page03</Url>
</Pages>
</Campaign>
</Response>
</AdXML>
Tag "Pages" can have any number of tags "Url" other tags might have only one value, like the tag "Name" for example.
Reading about SimpleXMLElement I ended up with the following code:
$xmlparsed = new SimpleXMLElement($xml); //my xml is being sent as variable
To display single values I am using the code below without a problem:
<?php echo $xmlparsed->Response[0]->Campaign[0]->Overview[0]->Name;?>
Everything works fine. But when I try to parse a tag with multiple lines I get only one line, and everytime I refresh the page it gives me a different "url" value. This is the code I am using:
<?php foreach ($xmlparsed->Response->Campaign->Pages as $Pages) {echo $Pages->Url, PHP_EOL;} ?>
According to PHP's site: http://php.net/manual/en/simplexml.examples-basic.php this should work, but it isn't.
Since I am not expert on PHP I am testing code on a trial-and-error basis.
What am I doing wrong here?
thanks in advance for any help.
You only have one Pages so you are only entering that foreach once. Try looping on the urls.
$xml = "<?xml version='1.0'?>
<AdXML>
<Response>
<Campaign>
<Overview>
<Name>strip</Name>
<Description>category</Description>
<Status>L</Status>
</Overview>
<Pages>
<Url>page01</Url>
<Url>page02</Url>
<Url>page03</Url>
</Pages>
</Campaign>
</Response>
</AdXML>";
$xmlparsed = new SimpleXMLElement($xml);
foreach ($xmlparsed->Response->Campaign->Pages->Url as $url) {
echo $url, PHP_EOL;
}
Output:
page01
page02
page03
You can also use XPath.
foreach( $xml->xpath( 'Response/Campaign/Pages/Url' ) as $url ) {
echo $url;
}

simplexml_load_file : XML declaration allowed only at the start of the document

I want to parse an XML document in PHP with SimpleXML.
I used simplexml_load_file and I got this error:
Warning: simplexml_load_file(): [myfile] parser error : XML declaration allowed only at the start of the document in /www/[...]/myphpfile.php on line 7
I have searched on Google and the problem seems to be that there is some whitespace before the tags in the XML document. I checked, there is no whitespace before.
Here is my code:
libxml_use_internal_errors(true);
$sxml=simplexml_load_file($xml);
if ($sxml) {
echo '<h2>'.$xml.'</h2>';
echo '<p>author: <textarea>';
foreach($sxml->author as $author) {
if($author!=$strXML)
echo $author.'\n';
}
echo '</textarea></p>';
}else {
echo "Failed loading XML\n";
foreach(libxml_get_errors() as $error)
echo "\t", $error->message;
}
Edit: error is Failed loading XML XML declaration allowed only at the start of the document Extra content at the end of the document
The first tag of the XML document is <?xml version="1.0" encoding="UTF-8"?>
I got this error following an example from Symfony2 :
<!-- validators.en.xliff -->
<?xml version="1.0"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file source-language="en" datatype="plaintext" original="file.ext">
<body>
<trans-unit id="1">
<source>author.name.not_blank</source>
<target>Saisissez un nom</target>
</trans-unit>
</body>
</file>
</xliff>
The problem was the comment on the first line !
Suppose, I found (actually I meet this error first time).
I tried an XML file that start very first line with <?xml ... (no error)
I tried an XML file that start very first line with [space or/and new line]<?xml ... (has error)
// both error (xml.xml contents)
<?xml version="1.0" encoding="UTF-8"?>
<response>
// and
<?xml version="1.0" encoding="UTF-8"?>
<response>
$xml = simplexml_load_file("xml.xml");
$xml = new SimpleXMLElement(file_get_contents("xml.xml"));
So, be sure XML file starts with <?xml ... or a valid XML tags (I mean 1. line), remove all spaces from first line.
Just strip whitespaces from beginning:
new \SimpleXMLElement(
trim($xmlString)
);
It worked for me.
Declare the $xsml first then use it in the if.

Hide XML declaration in files generated using PHP

I was tesing with a simple example of how to display XML in browser using PHP and found this example which works good
<?php
$xml = new DOMDocument("1.0");
$root = $xml->createElement("data");
$xml->appendChild($root);
$id = $xml->createElement("id");
$idText = $xml->createTextNode('1');
$id->appendChild($idText);
$title = $xml->createElement("title");
$titleText = $xml->createTextNode('Valid');
$title->appendChild($titleText);
$book = $xml->createElement("book");
$book->appendChild($id);
$book->appendChild($title);
$root->appendChild($book);
$xml->formatOutput = true;
echo "<xmp>". $xml->saveXML() ."</xmp>";
$xml->save("mybooks.xml") or die("Error");
?>
It produces the following output:
<?xml version="1.0"?>
<data>
<book>
<id>1</id>
<title>Valid</title>
</book>
</data>
Now I have got two questions regarding how the output should look like.
The first line in the xml file '', should not be displayed, that is it should be hidden
How can I display the TextNode in the next line. In total I am exepecting an output in this fashion
<data>
<book>
<id>1</id>
<title>
Valid
</title>
</book>
</data>
Is that possible to get the desired output, if so how can I accomplish that.
Thanks
To skip the XML declaration you can use the result of saveXML on the root node:
$xml_content = $xml->saveXML($root);
file_put_contents("mybooks.xml", $xml_content) or die("cannot save XML");
Please note that saveXML(node) has a different output from saveXML().
First question:
here is my post where all usable threads with answers are listed: How do you exclude the XML prolog from output?
Second question:
I don't know of any PHP function that outputs text nodes like that.
You could:
read xml using DomDocument and save each node as string
iterate trough nodes
detect text nodes and add new lines to xml string manually
At the end you would have the same XML with text node values in new line:
<node>
some text data
</node>

Categories