I have gone through a lot of the SimpleXML questions on this site. My data is a bit strange and I cannot change that. I am trying to get things like 'Building1' and 'Hostname1' from my data, so I can take that data and look up other data, then display it.
Here is a sample of my data:
<?xml version='1.0' encoding='UTF-8'?>
<results preview = '0'>
<result offset='0'>
<field k='hostname'>
<value h='1'><text>Hostname 1</text></value>
</field>
<field k='os'>
<value><text>Windows 7</text></value>
</field>
<field k='location'>
<value h='1'><text>Building 1</text></value>
<field>
</result>
<result offset='1'>
<field k='hostname'>
<value h='1'><text>Hostname 2</text></value>
</field>
<field k='os'>
<value><text>Windows 10</text></value>
</field>
<field k='location'>
<value h='1'><text>Building 2</text></value>
</field>
</result>
........
And here is how I am trying to look at it:
$xml = simplexml_load_file(data.xml);
print_r($xml);
$testArray = new SimpleXMLElement($xml);
$records = $testArray->results->result;
print_r($records);
For some reason I just cannot figure out how to get the data from the xml elements. If anyone can point me in the right direction, I'd appreciate it. I've tried many, many options. Thanks-
This is a really common mistake, but a really hard one to spot if you don't know what you're looking for: the first object you get back when parsing with XML is the root element, not something representing the document.
So in your case, $testArray is the element <results preview = '0'>, and you want $testArray->result not $testArray->results->result.
By the way, "testArray" is a bad name for this variable - it's not an array, it's an object.
I used xml as string in file
<?php
$sXmlString = <<<EOF
<?xml version="1.0" encoding="UTF-8"?>
<results preview = "0">
<result offset="0">
<field k="hostname">
<value h="1"><text>Hostname 1</text></value>
</field>
<field k="os">
<value><text>Windows 7</text></value>
</field>
<field k="location">
<value h="1"><text>Building 1</text></value>
</field>
</result>
<result offset="1">
<field k="hostname">
<value h="1"><text>Hostname 2</text></value>
</field>
<field k="os">
<value><text>Windows 10</text></value>
</field>
<field k="location">
<value h="1"><text>Building 2</text></value>
</field>
</result>
</results>
EOF;
echo '<pre>';
$xml = simplexml_load_string($sXmlString);
print_r($xml);
echo '<hr/>';
echo count($xml->result);
echo '<hr/>';
foreach($xml->result as $report)
{
var_dump($report);
echo '<hr/>';
}
In the code you can see $xml it self reference to the "results" (or root) element.
You need to travel from the root to child elements. $xml->result will give the result object in the results set and you need to go for loop as it as array of objects.
Related
i m trying to get some data from the xml out of prestashop api
To be exact, i want to create an array which will have as key the id (ex. 2) and value the name->language.
I am using simplexml_load_string to convert the xml to arrays
<?xml version="1.0" encoding="UTF-8"?>
<prestashop xmlns:xlink="http://www.w3.org/1999/xlink">
<category>
<id>
<![CDATA[2]]>
</id>
...
<name>
<language id="1" xlink:href="https://mosty.com/api/languages/1">
<![CDATA[Home]]>
</language>
</name>
<link_rewrite>
<language id="1" xlink:href="https://mosty.com/api/languages/1">
<![CDATA[home]]>
</language>
</link_rewrite>
...
</category>
</prestashop>
Please have a look at the code below. I suppose you have multiple <category> elements:
Code
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<prestashop xmlns:xlink="http://www.w3.org/1999/xlink">
<category>
<id>
<![CDATA[2]]>
</id>
<name>
<language id="1" xlink:href="https://mosty.com/api/languages/1">
<![CDATA[Home]]>
</language>
</name>
<link_rewrite>
<language id="1" xlink:href="https://mosty.com/api/languages/1">
<![CDATA[home]]>
</language>
</link_rewrite>
</category>
</prestashop>';
$obj = simplexml_load_string($xml);
$result = [];
foreach($obj->category as $item) {
$result[trim($item->id)] = trim($item->name->language);
}
var_dump($result);
Output
array(1) { [2]=> string(4) "Home" }
Ok so I have some XML data.
$mydata = <<<XML
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE fmresultset PUBLIC "-//FMI//DTD fmresultset//EN" "https://HIDDEN:443/fmi/xml/fmresultset.dtd">
<fmresultset xmlns="http://www.filemaker.com/xml/fmresultset" version="1.0">
<resultset count="1" fetch-size="1">
<record mod-id="27" record-id="754">
<field name="a_Constant_c">
<data>1</data>
</field>
<field name="a_Sch_ID_pk">
<data>100060</data>
</field>
<field name="a_SchoolHead_pk">
<data>100060_1</data>
</field>
<field name="b___Data_____________">
<data/>
</field>
<field name="b_1Name_School_Code_t">
<data>PJA</data>
</field>
<field name="b_1Name_School_t">
<data>Palmetto</data>
</field>
<field name="b_1Name_SchoolHead_t">
<data>John Doe</data>
</field>
<field name="b_Ad_Address1_t">
<data/>
</field>
<field name="b_Ad_Address2_t">
<data>123 Main St.</data>
</record>
</resultset>
</fmresultset>
XML;
Now what I want to do is basically be able to read the value of the data from a specific field and assign it to a variable.
So far I have something like this...
$xml = simplexml_load_string($mydata);
Now I want to be able to assign let's say the data in the field name b_1Name_School_Code_t (which is PJA)
So I think it should be something like this
$school = $xml->resultset->record->field->data;
echo "School Name: ".$school;
Then I would like to see on the screen
School Name: PJA
So what I am missing to be able to make this happen?
You are only getting to the first field element in your example, which is why you get 1. Instead, loop through all the field elements, and stop when you get to the one you need:
$xml = simplexml_load_string($mydata);
$fields = $xml->resultset->record->field;
foreach ($fields as $field) {
if ((string) $field->attributes()->name === "b_1Name_School_Code_t") {
echo "School name: ".$field->data; // School name: PJA
break;
}
}
Demo
I use SimpleXMLElement::attributes() to get the name attribute of the element (note the cast to string, otherwise you get an SimpleXMLElement)
However, it would make more sense to use XPath to go directly to the element you're after:
$xml = simplexml_load_string($mydata);
$xml->registerXPathNamespace("fmresultset", "http://www.filemaker.com/xml/fmresultset");
$node = $xml->xpath("//fmresultset:resultset/fmresultset:record/fmresultset:field[#name='b_1Name_School_Code_t']");
var_dump($node[0]->data); // PJA
Demo
Notice the namespace registration and the accessing of the first element, since xpath() returns an array of SimpleXMLElements
The XML that's received is below. How can I get the values ('AI', '3', '20.78'...) and display them in PHP?
The values are always returned in that order but the length can vary.
<?xml version="1.0" encoding="UTF-8"?>
<Data>
<Item Type="AI" Chan="3" Value="20.78" Manual="OFF" Min="0.00" Max="100.00" Units="degC" Name="Workshop Temp" />
</Data>
Any ideas would be much appreciated!
You might find the documentation of SimpleXMLElement::attributes useful,
SimpleXMLElement::attributes — Identifies an element's attributes
Return Values
Returns a SimpleXMLElement object that can be iterated over to loop through the attributes on the tag.
Returns NULL if called on a SimpleXMLElement object that already represents an attribute and not a tag.
here is how you should use it:
$str = <<< XML
<?xml version="1.0" encoding="UTF-8"?>
<Data>
<Item Type="AI" Chan="3" Value="20.78" Manual="OFF" Min="0.00" Max="100.00" Units="degC" Name="Workshop Temp" />
</Data>
XML;
$xml = simplexml_load_string($str);
foreach($xml->Item[0]->attributes() as $key => $att) {
echo $att."\n";
}
I am trying to parse an XML file with php SimpleXML and xpath and having problems getting the paths right and accessing attribute values. Any help appreciated.
Here is my xml file:-
<message:MessageGroup xmlns="http://mynamespace.com">
<Book>
<BookKey>
<Value concept="TITLE" value="Gone Girl"/>
<Value concept="AUTHOR" value="Gillian Flynn"/>
</BookKey>
<Sales>
<Month>Jan</Month>
<Number value="20"/>
</Sales>
<Sales>
<Month>Feb</Month>
<Number value="15"/>
</Sales>
<Sales>
<Month>Mar</Month>
<Number value="30"/>
</Sales>
</Book>
<Book>
<BookKey>
<Value concept="TITLE" value="Inferno"/>
<Value concept="AUTHOR" value="Dan Brown"/>
</BookKey>
<Sales>
<Month>Jan</Month>
<Number value="10"/>
</Sales>
<Sales>
<Month>Feb</Month>
<Number value="15"/>
</Sales>
<Sales>
<Month>Mar</Month>
<Number value="3"/>
</Sales>
</Book>
</message:MessageGroup>
I need to parse this to get the following output:-
Gone Girl,Gillian Flynn,Jan,20
Gone Girl,Gillian Flynn,Feb,15
Gone Girl,Gillian Flynn,Mar30
Inferno,Dan Brown,Jan,10
Inferno,Dan Brown,Feb,15
Inferno,Dan Brown,Mar,3
I have written the following code:-
<?php
$xmlfile = 'Books.xml';
$xml = simplexml_load_file($xmlfile);
$namespace = 'http://mynamespace.com';
$xml->registerXPathNamespace('ns',$namespace);
$books = $xml->xpath('//ns:Book');
//loop through each book -
foreach($books as $book) {
$values = $xml->xpath('ns:BookKey/Value');
$bookkeys= array();
//loop through each Book's BookKey Values and push them to array -
foreach($values as $value){
array_push($bookkeys, $value->attributes()->value);
}
$sales = $xml->xpath('ns:Sales');
//loop through each Book's Sales and write out Month and Number value after the book key values -
foreach($sales as $sale){
foreach($bookkeys as $bk){
echo $bk.",";
}
echo $sale->Month;
echo ",";
echo $sale->Number->attributes()->value;
echo "\n";
}
}
?>
From a var_dump, the $books array appears to be ok; $values and $sales are empty arrays though, so clearly the paths are not right. I have tried leaving out the namespace but still get an empty array; I want to avoid pulling out all the instances of values and sales in the file as opposed to just the ones for each particular book.
You are missing the namespace definition for the prefix message.
To get the value from Value, message:MessageGroup/ns:BookKey/ns:Value/#value will be the XPath to use.
So I am working with an API that returns results in XML. Let's just say for argument sake I am returned the following:
<?xml version="1.0" encoding="UTF-8"?>
<Properties>
<Property>
<Name>Joes Crab Shack</Name>
<Address>111 Shack Street</Address>
</Property>
<Property>
<Name>Johns Shoe Store</Name>
<Address>123 Shoe Avenue</Address>
</Property>
</Properties>
Now I am using PHP and I get the results into a variable. So essentially this happens:
$xml_results = '<?xml version="1.0" encoding="UTF-8"?><Properties><Property><Name>Joes Crab Shack</Name><Address>111 Shack Street</Address></Property><Property><Name>Johns Shoe Store</Name><Address>123 Shoe Avenue</Address></Property></Properties>';
Now how can I treat this as an XML document and for example loop through it and print out all property names?
Something like this should get the job done.
$request_xml = '<?xml version="1.0" encoding="UTF-8"?>
<Properties>
<Property>
<Name>Joes Crab Shack</Name>
<Address>111 Shack Street</Address>
</Property>
<Property>
<Name>Johns Shoe Store</Name>
<Address>123 Shoe Avenue</Address>
</Property>
</Properties>';
$xml = simplexml_load_string($request_xml);
$i = 0;
while ($xml->Property[$i])
{
echo $xml->Property[$i]->Name;
echo $xml->Property[$i]->Address;
$i++;
}
Deserialize into an xml tree, try SimpleXML. That way you can access that data in a more convenient fashion and grab specific xml elements..