When I try to Import xml file, it returns an error:
xmlParseCharRef: invalid xmlChar value 4" because of $amp; in xml <STOCKGROUP >NAME="ABC & Glass" RESERVEDNAME="">
Here is code I'm using to read xml file data
function add_product_type()
{
print_r($_FILES);
if (isset($_FILES['product_type_file']) && ($_FILES['product_type_file']['error'] == UPLOAD_ERR_OK)) {
$use_errors = libxml_use_internal_errors(true);
$response = simplexml_load_file($_FILES['product_type_file']['tmp_name']);
print_r($response);
foreach($response->BODY->IMPORTDATA as $key => $value) {
foreach($value->REQUESTDATA->TALLYMESSAGE as $key => $values) {
if (strstr("&", $values->STOCKGROUP->attributes())) {
$name = str_replace("&", "&", $values->STOCKGROUP->attributes());
}
else {
$name = $values->STOCKGROUP->attributes();
}
echo $name . ",";
}
}
if ($response == false) {
echo "Failed loading XML\n";
foreach(libxml_get_errors() as $error) {
echo "\t", $error->message;
}
}
}
}
XML has no notion of HTML entities. As a hack, you can decode the entities first with
$html = html_entity_decode($file_contents, ENT_QUOTES, "utf-8");
and then try parse $html with the XML parser. Just hope it's tolerant enough, because HTML is still not valid XML.
The good news is that you can then remove the if (strstr("&", hack because that is taken care of by html_entity_decode().
Your XML sample isn't the same data as your getting the error with and processes OK, but this doesn't mean that your code is correct. In
your main loop, you use $values->STOCKGROUP->attributes() as the name, but if you did a print_r() of this value, you will see it comes out with a list of all of the attribute values and your code will combine them all into one string.
SimpleXMLElement Object
(
[#attributes] => Array
(
[NAME] => Alluminium Section & Glass
[RESERVEDNAME] =>
)
)
If you just want the NAME attribute of <STOCKGROUP NAME="Alluminium Section & Glass" RESERVEDNAME="">, then use STOCKGROUP['NAME']. Also rather than just substitute &, use html_entity_decode() to convert any characters in the name.
foreach($response->BODY->IMPORTDATA as $key => $value) {
foreach($value->REQUESTDATA->TALLYMESSAGE as $key => $values) {
$name = html_entity_decode((string)$values->STOCKGROUP['NAME']);
echo $name . ",";
}
}
This code with the sample you provide outputs...
Alluminium Section & Glass,
Update:
Check the file being loaded...
$data = file_get_contents($_FILES['product_type_file']['tmp_name']);
echo $data;
$use_errors = libxml_use_internal_errors(true);
$response = simplexml_load_string($data);
echo $response->asXML();
Related
I have one .usx file and i want to fetch data from it accordingly. But now finding any way to do it. Please help me out.
usx file link
I had tried the below code
$xml=simplexml_load_file("uploads/American-Standard-Version-Bible-master/usx/01-GEN.usx") or die("Error: Cannot create object");
foreach($xml->children() as $book)
{
// echo "<pre>";
// print_r($book);
echo "Book Name:".$book->attributes()->code."<br/>";
if($book->attributes()->number != "" )
{
echo "chapter : ".$book->attributes()->number."<br />";
}
foreach ($book->verse as $value) {
// echo "<pre>";
// print_r($value);
echo "Verses Number : ".$value->attributes()->number."<br />";
}
echo "book : ".$book."<br />";
echo "<hr/>";
}
}
OUTPUT :
I want output one by one of all verse rather then all at once
The problem can be that SimpleXML just doesn't give you enough control over XML that has more than a simple structure. So trying to get the text inbetween the <verse> tags is difficult. If instead you use DOMDocument, this has much more detail and control over your document.
The code below just reads through the document and mostly checks the node names to work out what it should be displaying - so for the <chapter> element, it will output the number attribute. The only difference is that when looking through the main <para> elements which contain the <verse> and text mixed together, it looks for a node type of XML_TEXT_NODE, which as you might expect is the verse text, so it just outputs the contents at that point.
$dom = new DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->load("01-GEN.usx");
foreach ( $dom->documentElement->childNodes as $element ) {
if ( $element->nodeName == "book" ) {
echo "Book Name:".$element->getAttribute("code")."<br/>";
}
else if ( $element->nodeName == "chapter" ) {
echo "chapter:".$element->getAttribute("number")."<br/>";
}
else if ( $element->nodeName == "para" ) {
foreach ( $element->childNodes as $verse ) {
if ( $verse->nodeName == "verse" ) {
echo "verse:".$verse->getAttribute("number")."<br/>";
}
else if ( $verse->nodeType == XML_TEXT_NODE ) {
echo $verse->nodeValue."<br/>";
}
}
}
}
I have such php code:
$xml = #simplexml_load_file('2.xml', 'SimpleXMLElement',LIBXML_NOCDATA);
print_r($xml);
How to get values of:
DialingNumber,StartTime,AnswerTime ?
foreach ($xml as $show)
{
echo (string)$show['DialedNumber'];
echo (string)$show['AnswerNumber'];
echo (string)$show['WaitDuration'];
}
NOT WORKING ! How to get values of: DialingNumber,StartTime,AnswerTime ?
There are problems with the the XML file itself, which can be 'corrected' with just replacing some of the entities with some dummy data. The second part is to reference the correct path to the data you want to output.
$filename = '2.xml';
$data = file_get_contents($filename);
$data = str_replace(["&rs", "&rc"], "", $data); // Remove entity references
$xml = simplexml_load_string($data);
foreach ($xml->Tablix1->DialedNumber_Collection->DialedNumber->Details_Collection->Details
as $details)
{
echo (string)$details['DialedNumbers'].PHP_EOL;
echo (string)$details['AnswerNumber'].PHP_EOL;
echo (string)$details['WaitDuration'].PHP_EOL;
}
Can you try as below?
foreach ($xml as $show)
{
echo (string)$show[0]['DialedNumber'];
echo (string)$show[0]['AnswerNumber'];
echo (string)$show[0]['WaitDuration'];
}
I am using the following code to print the output of the jSON response but when I try to print
echo $obj->HotelListResponse->customerSessionId; // This is working.
echo $obj->HotelListResponse->HotelList->HotelSummary->name; // This is not working.
When the response contains only one node then its printing perfectly but when there are multiple nodes with same name then its not printing. I tried using foreach just like the below. I also tried using while loop but still I am unable to print the list of hotel names.
My jSON decoded output is like http://pastebin.com/Fr21DkEk
Total code:
$url = "https://api.eancdn.com/ean-services/rs/hotel/v3/list?cid=55505&minorRev=99&apiKey=cbrzfta369qwyrm9t5b8y8kf&locale=en_AU¤cyCode=AUD&xml=<HotelListRequest><city>Brisbane</city><stateProvinceCode>QLD</stateProvinceCode><countryCode>AU</countryCode><arrivalDate>10/16/2014</arrivalDate><departureDate>10/18/2014</departureDate><RoomGroup><Room><numberOfAdults>2</numberOfAdults></Room></RoomGroup><numberOfResults>25</numberOfResults></HotelListRequest>";
$json = file_get_contents($url);
$obj = json_decode($json);
foreach($obj as $val) {
echo $val->HotelListResponse->HotelList->HotelSummary->name;
}
Try this
foreach($obj->HotelListResponse->HotelList->HotelSummary as $val) {
echo $val->name . '<br/>';
}
HotelSummary is an array:
echo $val->HotelListResponse->HotelList->HotelSummary[0]->name;
If you want all of the hotel summaries:
foreach($obj as $val) {
foreach($val->HotelListResponse->HotelList->HotelSummary as $sum) {
echo $sum->name;
}
}
Yes you can directly access them inside the foreach. Like this:
foreach($obj->HotelListResponse->HotelList->HotelSummary as $val) {
// ^^
// since you're interested on just names, you can point it directly on that object, then each of that batch is in `$val`
echo $val->name . '<br/>';
}
// or start from the parent
foreach($obj as $values) {
$customerSessionId = $values->customerSessionId;
echo $customerSessionId . '<hr/>';
$hotelList = $values->HotelList;
foreach($hotelList->HotelSummary as $hotelsummary) {
echo $hotelsummary->name . '<br/>';
}
}
I am trying to pull text from a single element in an xml file, i was able to pull the entire file but i really only need a couple of lines from the file...
On this page i was able to pull the entire xml file ( http://smyrnainlet.com/testing.php )
But when i try to just single out one line from that file.
http://smyrnainlet.com/current_data.php
This is the error i am receiving:
Fatal error: Call to a member function getbyElementID() on a non-object in /home/content/74/8620474/html/current_data.php on line 9
If anyone could help me that would be amazing, i have been struggling with this for hours.
This is my code:
<?php
function startElemHandler($parser, $name, $attribs)
{
if (strcasecmp($name, "current_observation") ==0 ) {
echo "<div id='waves'>\n";
}
if (strcasecmp($name, "wave_height_ft") ==0) {
$waveHeight->getbyElementID("wave_height_ft");
echo $waveHeight->asXML();
}
}
function endElemHandler($parser, $name)
{
if (strcasecmp($name, "current_observation") ==0 ) {
echo "</div>";
}
}
$parser = xml_parser_create();
xml_set_element_handler($parser, startElemHandler, endElemHandler);
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
$strXML = implode("",file("http://www.weather.gov/xml/current_obs/41009.xml"));
xml_parse($parser, $strXML);
xml_parser_free($parser);
?>
You have a few fundamental flaws with your code but you are essentially asking how to parse an XML file. I suggest using PHP's DOMDocument with DOMXPath to extract the data you need. Here is some example code:
$xml = file_get_contents('weather.xml');
$dom = new DOMDocument();
#$dom->loadHTML($xml);
$domx = new DOMXPath($dom);
$entries = $domx->evaluate("//wave_height_ft");
$arr = array();
foreach ($entries as $entry) {
$arr[] = '<' . $entry->tagName . '>' . $entry->nodeValue . '</' . $entry->tagName . '>';
}
print_r($arr);
$waveHeight seem not defined (not in scope) wher you try to use it!
you can
pass it as argument
use the global statement
create a class
I'm creating a "Madlibs" page where visitors can create funny story things online. The original files are in XML format with the blanks enclosed in XML tags
(Such as blablabla <PluralNoun></PluralNoun> blablabla <Verb></Verb> ).
The form data is created using XSL and the results are saved using a $_POST array. How do I post the $_POST array between the matching XML tags and then display the result to the page? I'm sure it uses a "foreach" statement, but I'm just not familiar enough with PHP to figure out what functions to use. Any help would be great.
Thanks,
E
I'm not sure if I understood your problem quite well, but I think this might help:
// mocking some $_POST variables
$_POST['Verb'] = 'spam';
$_POST['PluralNoun'] = 'eggs';
// original template with blanks (should be loaded from a valid XML file)
$xml = 'blablabla <PluralNoun></PluralNoun> blablabla <Verb></Verb>';
$valid_xml = '<?xml version="1.0"?><xml>' . $xml . '</xml>';
$doc = DOMDocument::loadXML($valid_xml, LIBXML_NOERROR);
if ($doc !== FALSE) {
$text = ''; // used to accumulate output while walking XML tree
foreach ($doc->documentElement->childNodes as $child) {
if ($child->nodeType == XML_TEXT_NODE) { // keep text nodes
$text .= $child->wholeText;
} else if (array_key_exists($child->tagName, $_POST)) {
// replace nodes whose tag matches a POST variable
$text .= $_POST[$child->tagName];
} else { // keep other nodes
$text .= $doc->saveXML($child);
}
}
echo $text . "\n";
} else {
echo "Failed to parse XML\n";
}
Here is PHP foreach syntax. Hope it helps
$arr = array('fruit1' => 'apple', 'fruit2' => 'orange');
foreach ($arr as $key => $val) {
echo "$key = $val\n";
}
and here is the code to loop thru your $_POST variables:
foreach ($_POST as $key => $val) {
echo "$key = $val\n";
// then you can fill each POST var to your XML
// maybe you want to use PHP str_replace function too
}