simplexml_load_file can't load an XML file - php

I'm trying to do some very basic parsing of XML data but am failing miserably.
I have a metadata.xml file as such:
<?xml version="1.0" encoding="UTF-8" ?>
<metadata>
<page>
<filename>products.php</filename>
<title>Best selection of products in Anytown, USA</title>
<description>We sell quality products</description>
</page>
<page>
<filename>services.com</filename>
<title>Great services anywhere within Anytown</title>
<description>Our services are pretty good</description>
</page>
</metadata>
I'm attempting to get a result for a specific XML entry using the code below:
<?php
$str = simplexml_load_file("metadata.xml") or die("Couldn't load file");
$data = new SimpleXMLElement($str);
// Find the element with specific filename
$nodes = $data->xpath('//metadata/page/filename[.="products.php"]/parent::*');
$result = $nodes[0];
echo "Title: " . $result->title . "\n";
echo "Description: " . $result->description . "\n";
?>
This results in an error:
Warning: SimpleXMLElement::__construct(): Entity: line 4: parser error : Start tag expected, '<' not found in /var/www/html/php_xml_test.php on line 10
Fatal error: Uncaught Exception: String could not be parsed as XML in /var/www/html/php_xml_test.php:10 Stack trace: #0 /var/www/html/php_xml_test.php(10): SimpleXMLElement->__construct('\n\t\n\t\n') #1 {main} thrown in /var/www/html/php_xml_test.php on line 10
If I load the content of the XML file right into the php file everything works fine.
I've read through a bunch of related posts here but can't figure out where I'm going wrong.
Thanks!

As per http://php.net/manual/en/simplexmlelement.construct.php I adjusted the code like that:
<?php
$data = new SimpleXMLElement('metadata.xml', 0, TRUE);
// Find the element with specific filename
$nodes = $data->xpath('//metadata/page/filename[.="services.php"]/parent::*');
$result = $nodes[0];
echo "Title: " . $result->title . "\n";
echo "Description: " . $result->description . "\n";
?>

Related

converting XML file into HTML file

I have an XML file and i want to print the data as html which contains multiple tags. I have looped the file using foreach but it only prints the tags of the XML file. The text inside the tags are not printing.
This is my XML file:
<?xml version="1.0" encoding="UTF-8"?>
<Jobs>
<APPLICATION>
<ACTION><![CDATA[MODIFY]]></ACTION>
<JOBID><![CDATA[21494017]]></JOBID>
<JOBTITLE><![CDATA[dummy MNC&#x27;S of Pune.]]></JOBTITLE>
<JobDescription><![CDATA[dummy]]></JobDescription>
<KEYSKILLS><![CDATA[dummy]]></KEYSKILLS>
<SUMMARY><![CDATA[dummy]]></SUMMARY>
</APPLICATION>
<APPLICATION>
<ACTION><![CDATA[MODIFY]]></ACTION>
<JOBID><![CDATA[21494017]]></JOBID>
<JOBTITLE><![CDATA[dummy MNC&#x27;S of Pune.]]></JOBTITLE>
<JobDescription><![CDATA[dummy]]></JobDescription>
<KEYSKILLS><![CDATA[dummy]]></KEYSKILLS>
<SUMMARY><![CDATA[dummy]]></SUMMARY>
</APPLICATION>
AND SO ON..........................................
</Jobs>
The issue i am facing is that when i loop it only print the tags like:
Jobs
APPLICATION:
APPLICATION:
APPLICATION:
APPLICATION:
APPLICATION:
Following is the code that i am using to print the XML file:
$xml=simplexml_load_file("fli.xml");
echo $xml->getName() . "<br>";
foreach($xml->children() as $child)
{
echo $child->getName() . ": " . $child . "<br>";
}
I am not able to print the data inside the APPLICATION. How do I do it?
The APPLICATION element doesn't contain text. You should do one more inner cycle on $child to get the text inside the inner tags. At the moment you're just cycling on the APPLICATIONs.
$xml=simplexml_load_file("fli.xml");
echo $xml->getName() . "<br>";
foreach($xml->children() as $child)
{
foreach($child->children() as $inner) {
echo $inner->getName() . ": " . $inner. "<br>";
}
}

How do I correctly structure this xml with variables?

How do I correctly structure this XML document. This document will be embedded within a PHP script and send orders to a folder on the server.
Also, can you please look at the FOR EACH loop for products?
Thanks for your help!
(Variables from order form)
$order_id = '1234';
$product_id = '5678';
$prodduct_sku = '0123';
$product_retail = '123.45';
define("FILENAME", "orders/order" . $order_id . ".xml");
$xml_output = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n";
$xml_output .= "<document type="850X-02" timestamp= $timestamp id="123456789>";
$xml_output .= "<order id=" . $order_id .>";
for ($x=0; $x<=100; $x++)
{
$xml_output .= "<line id=" . $x . "quantity=" . $quantity . />";
$xml_output .= "<product id=" . $product_id . "supplier_sku=" . $product_sku . "retail_price=" . $product_retail . />";
}
$xml_output .= "</document>';
// CONVERT THE ARRAY TO A STRING
$str = implode($xml_output);
// WRITE IT INTO THE FILE SYSTEM
file_put_contents(FILENAME, $str);
You don't close your order tag. Add </order> somewhere after the line loop.
Beyond that, you may consider using an IDE that provides robust xml formatting and validation, or you can use a web-based xml validator to verify that the xml you create is valid.
Another tip for testing xml generation code is to get a valid xml sample for the target system, then refine your code until you can generate that example text. Using file diff tools you can quickly identify things like missing tags, elements instead of attributes, or other common errors.

Generate XML with 'SimpleXMLElement' with some empty filelds?

$sitemap .= " " . '<orders>' . "\n" .
"\t" . '<idKlant>' . $id. '</idKlant>' .
"\n\t" . '<emptyfield></emptyfield>' .
"\n\t" . '<date>' . $verzenddatum . '</date>' . //remaining to get
"\n " . '</orders>' . "\n";
For generating XMl, I am using below code
$xmlobj = new SimpleXMLElement($sitemap);
$xmlobj->asXML("orders.xml");
Output of orders.xml
<orders>
<idKlant>12</idKlant>
<emptyfield/>
<date>30-12-2012</date>
</orders>
What i want is: for Empty xml field there should be Opening and Closing tag as well
<orders>
<idKlant>12</idKlant>
<emptyfield></emptyfield>
<date>30-12-2012</date>
</orders>
Is it possible? OR should i add black space?
As Rolando Isidoro said you can't do it with SimpleXML. But you can always switch to the DOM. Both extension use the same underlying library and representation, so there is very little overhead.
DOMDocument::saveXML can take libxml options as the second parameter and there is LIBXML_NOEMPTYTAG which does exactly what you want.
e.g.
<?php
$o = new SimpleXMLELement(data());
$docRoot = dom_import_simplexml($o);
echo $docRoot->ownerDocument->savexml($docRoot,LIBXML_NOEMPTYTAG);
function data() {
return '<orders>
<idKlant>12</idKlant>
<emptyfield/>
<date>30-12-2012</date>
</orders>';
}
prints
<orders>
<idKlant>12</idKlant>
<emptyfield></emptyfield>
<date>30-12-2012</date>
</orders>

getTraceAsString() printing out as one whole line

I am using the php method getTraceAsString() which will pring out my error messages like:
#0 /var/www/wordpress/wp-content/themes/Aisis-Framework/AisisCore/Template/Builder.php(147): AisisCore_Template_Builder->_render_template_array(Array, 'navigation') #1 /var/www/wordpress/wp-content/themes/Aisis-Framework/index.php(3): AisisCore_Template_Builder->render_view('navigation') #2 /var/www/wordpress/wp-includes/template-loader.php(47): include('/var/www/wordpr...') #3 /var/www/wordpress/wp-blog-header.php(16): require_once('/var/www/wordpr...') #4 /var/www/wordpress/index.php(17): require('/var/www/wordpr...') #5 {main}
As you can see is one giant string. The example they gave prints out the trace as separate lines. is there something I have to do to get that?
It's a string with line breaks, not HTML. Look at the source code of your page.
Either wrap the output in <pre></pre> tags or replace the line break with HTML line breaks.
preg_replace("/\n/", '<br>', $trace);
I have made some function for ZF2 error log , along with formatting of,
$e->getTraceAsString();
Hope this might help you.
public function Errorcatch(\Exception $e) {
$log = "<div class='error_main'>";
$log.= "<br /><b>Error Time :</b>" . date('Y-m-d H:i:s A');
$log.= "<br /><b>Error Code :</b>" . $e->getCode();
$log.= "<br /><b>Error Message :</b>" . $e->getMessage();
$log.="<br /><b>Error File :</b>" . $e->getFile();
$log.="<br /><b>Error File Line :</b>" . $e->getLine();
$log.="<br /><b>Error Trace :</b><br />" . preg_replace("/\n/", '<br>', $e->getTraceAsString());
$log.= "</div>";
$this->getServiceLocator()->get('Zend\Log')->info($log); // This line write the log file.
}

print all triples into RDF files

i'm using rdfapi-php library and trying to open my RDF file.
Here are the code edited from the tutorial to show the content parsed into the way the library explain.
//include RDF API
define("RDFAPI_INCLUDE_DIR", "C:/OpenSA/Apache/htdocs/rdf_api/api/");
include(RDFAPI_INCLUDE_DIR . "RDFAPI.php");
// Filename of an RDF document
$base="example1.rdf";
// Create a new MemModel
$model = ModelFactory::getDefaultModel();
// Load and parse document
$model->load($base);
// Get Iterator from model
$it = $model->getStatementIterator();
// Traverse model and output statements
while ($it->hasNext()) {
$statement = $it->next();
echo "Statement number: " . $it->getCurrentPosition() . "<BR>";
echo "Subject: " . $statement->getLabelSubject() . "<BR>";
echo "Predicate: " . $statement->getLabelPredicate() . "<BR>";
echo "Object: " . $statement->getLabelObject() . "<P>";
}
that is the output
Statement number: 0
Subject: http://www.w3.org/Home/Lassila
Predicate: http://description.org/schema/Creator
Object: e85740
Statement number: 1
Subject: e85740
Predicate: http://www.w3.org/1999/02/22-rdf-syntax-ns#type
Object: http://description.org/schema/Person
My problem is that in the variable $base i will have an array with the name of all my RDF files. How i can edit the script to get the content of all the file of the array and after that print every RDF triple?
Regards

Categories