Issues loading XML file data into a PHP object - php

I’m setting up a PHP site which will gather information from a Dell iDRAC. I want to use the returned information to create a PHP object. The information returned from the first part of the script looks like this.
<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://www.w3.org/2003/05/soap-envelope" xmlnwsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlnwsen="http://schemas.xmlsoap.org/ws/2004/09/enumeration" xmlnn1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_SystemView" xmlnxsi="http://www.w3.org/2001/XMLSchema-instance">
<Header>
<To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</To>
<Action>http://schemas.xmlsoap.org/ws/2004/09/enumeration/PullResponse</Action>
<RelatesTo>uuid:e5ef952f-fb48-1b48-8003-06c7395d1500</RelatesTo>
<MessageID>uuid:36a3a786-fb4c-1b4c-8012-fc140555dbe0</MessageID>
</Header>
<Body>
<PullResponse>
<Items>
<DCIM_SystemView>
<AssetTag/>
<BIOSReleaseDate>01/20/2014</BIOSReleaseDate>
<BIOSVersionString>2.1.2</BIOSVersionString>
<BaseBoardChassisSlot>NA</BaseBoardChassisSlot>
<BatteryRollupStatus>1</BatteryRollupStatus>
<BladeGeometry>255</BladeGeometry>
<BoardPartNumber>03015MA01</BoardPartNumber>
<BoardSerialNumber>CN7475128I0205</BoardSerialNumber>
<CPLDVersion>1.0.0</CPLDVersion>
<CPURollupStatus>1</CPURollupStatus>
<ChassisModel/>
<ChassisName>Main System Chassis</ChassisName>
<ChassisServiceTag>5P5KMW1</ChassisServiceTag>
<ChassisSystemHeight>5</ChassisSystemHeight>
<DeviceDescription>System</DeviceDescription>
<ExpressServiceCode>12404926945</ExpressServiceCode>
<FQDD>System.Embedded.1</FQDD>
<FanRollupStatus>1</FanRollupStatus>
<HostName/>
<InstanceID>System.Embedded.1</InstanceID>
<LastSystemInventoryTime>20140608040932.000000+000</LastSystemInventoryTime>
<LastUpdateTime>20140522204842.000000+000</LastUpdateTime>
<LicensingRollupStatus>1</LicensingRollupStatus>
<LifecycleControllerVersion>2.1.0</LifecycleControllerVersion>
<Manufacturer>Dell Inc.</Manufacturer>
<MaxCPUSockets>2</MaxCPUSockets>
<MaxDIMMSlots>12</MaxDIMMSlots>
<MaxPCIeSlots>6</MaxPCIeSlots>
<MemoryOperationMode>OptimizerMode</MemoryOperationMode>
<Model>PowerEdge T420</Model>
<NodeID>5P5KMW1</NodeID>
<PSRollupStatus>1</PSRollupStatus>
<PlatformGUID>31574d4f-c0b5-4b80-3510-00504c4c4544</PlatformGUID>
<PopulatedCPUSockets>2</PopulatedCPUSockets>
<PopulatedDIMMSlots>4</PopulatedDIMMSlots>
<PopulatedPCIeSlots>1</PopulatedPCIeSlots>
<PowerCap>317</PowerCap>
<PowerCapEnabledState>3</PowerCapEnabledState>
<PowerState>2</PowerState>
<PrimaryStatus>1</PrimaryStatus>
<RollupStatus>1</RollupStatus>
<ServiceTag>5P5KMW1</ServiceTag>
<StorageRollupStatus>1</StorageRollupStatus>
<SysMemErrorMethodology>6</SysMemErrorMethodology>
<SysMemFailOverState>NotInUse</SysMemFailOverState>
<SysMemLocation>3</SysMemLocation>
<SysMemMaxCapacitySize>393216</SysMemMaxCapacitySize>
<SysMemPrimaryStatus>1</SysMemPrimaryStatus>
<SysMemTotalSize>16384</SysMemTotalSize>
<SystemGeneration>12G Monolithic</SystemGeneration>
<SystemID>1273</SystemID>
<SystemRevision>0</SystemRevision>
<TempRollupStatus>1</TempRollupStatus>
<UUID>4c4c4544-0050-3510-804b-b5c04f4d5731</UUID>
<VoltRollupStatus>1</VoltRollupStatus>
<smbiosGUID>44454c4c-5000-1035-804b-b5c04f4d5731</smbiosGUID>
</DCIM_SystemView>
</Items>
<EndOfSequence/>
</PullResponse>
</Body>
</Envelope>
When I try to use the simplexml_load_string function, it returns the following errors and does not process the data as a string.
PHP Warning: simplexml_load_string(): Entity: line 1: parser error : XML declaration allowed only at the start of the document in php shell code on line 1
PHP Warning: simplexml_load_string(): in php shell code on line 1
PHP Warning: simplexml_load_string(): ^ in php shell code on line 1
However, if I use the EXACT same XML and manually create the variable like this :
<<<XML
<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://www.w3.org/2003/05/soap-envelope" xmlnwsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlnwsen="http://schemas.xmlsoap.org/ws/2004/09/enumeration" xmlnn1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_SystemView" xmlnxsi="http://www.w3.org/2001/XMLSchema-instance">
<Header>
<To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</To>
<Action>http://schemas.xmlsoap.org/ws/2004/09/enumeration/PullResponse</Action>
<RelatesTo>uuid:641403a8-fb4a-1b4a-8003-06c7395d1500</RelatesTo>
<MessageID>uuid:b4caac95-fb4d-1b4d-8051-fc140555dbe0</MessageID>
</Header>
<Body>
<PullResponse>
<Items>
<DCIM_SystemView>
<AssetTag/>
<BIOSReleaseDate>01/20/2014</BIOSReleaseDate>
<BIOSVersionString>2.1.2</BIOSVersionString>
<BaseBoardChassisSlot>NA</BaseBoardChassisSlot>
<BatteryRollupStatus>1</BatteryRollupStatus>
<BladeGeometry>255</BladeGeometry>
<BoardPartNumber>03015MA01</BoardPartNumber>
<BoardSerialNumber>CN7475128I0205</BoardSerialNumber>
<CPLDVersion>1.0.0</CPLDVersion>
<CPURollupStatus>1</CPURollupStatus>
<ChassisModel/>
<ChassisName>Main System Chassis</ChassisName>
<ChassisServiceTag>5P5KMW1</ChassisServiceTag>
<ChassisSystemHeight>5</ChassisSystemHeight>
<DeviceDescription>System</DeviceDescription>
<ExpressServiceCode>12404926945</ExpressServiceCode>
<FQDD>System.Embedded.1</FQDD>
<FanRollupStatus>1</FanRollupStatus>
<HostName/>
<InstanceID>System.Embedded.1</InstanceID>
<LastSystemInventoryTime>20140608040932.000000+000</LastSystemInventoryTime>
<LastUpdateTime>20140522204842.000000+000</LastUpdateTime>
<LicensingRollupStatus>1</LicensingRollupStatus>
<LifecycleControllerVersion>2.1.0</LifecycleControllerVersion>
<Manufacturer>Dell Inc.</Manufacturer>
<MaxCPUSockets>2</MaxCPUSockets>
<MaxDIMMSlots>12</MaxDIMMSlots>
<MaxPCIeSlots>6</MaxPCIeSlots>
<MemoryOperationMode>OptimizerMode</MemoryOperationMode>
<Model>PowerEdge T420</Model>
<NodeID>5P5KMW1</NodeID>
<PSRollupStatus>1</PSRollupStatus>
<PlatformGUID>31574d4f-c0b5-4b80-3510-00504c4c4544</PlatformGUID>
<PopulatedCPUSockets>2</PopulatedCPUSockets>
<PopulatedDIMMSlots>4</PopulatedDIMMSlots>
<PopulatedPCIeSlots>1</PopulatedPCIeSlots>
<PowerCap>317</PowerCap>
<PowerCapEnabledState>3</PowerCapEnabledState>
<PowerState>2</PowerState>
<PrimaryStatus>1</PrimaryStatus>
<RollupStatus>1</RollupStatus>
<ServiceTag>5P5KMW1</ServiceTag>
<StorageRollupStatus>1</StorageRollupStatus>
<SysMemErrorMethodology>6</SysMemErrorMethodology>
<SysMemFailOverState>NotInUse</SysMemFailOverState>
<SysMemLocation>3</SysMemLocation>
<SysMemMaxCapacitySize>393216</SysMemMaxCapacitySize>
<SysMemPrimaryStatus>1</SysMemPrimaryStatus>
<SysMemTotalSize>16384</SysMemTotalSize>
<SystemGeneration>12G Monolithic</SystemGeneration>
<SystemID>1273</SystemID>
<SystemRevision>0</SystemRevision>
<TempRollupStatus>1</TempRollupStatus>
<UUID>4c4c4544-0050-3510-804b-b5c04f4d5731</UUID>
<VoltRollupStatus>1</VoltRollupStatus>
<smbiosGUID>44454c4c-5000-1035-804b-b5c04f4d5731</smbiosGUID>
</DCIM_SystemView>
</Items>
<EndOfSequence/>
</PullResponse>
</Body>
</Envelope>
XML;
It works like a charm. So, my question is simple. How can I tell PHP to process the string the same way it processes the XML like it does if the XML identifier is used. I have tried to reprocess the string like this:
$new_string = <<<XML
$string
XML;
But no go. Any other ideas?

Are you using file_get_contents to actually load the XML file into a string before using simplexml_load_string which—as the name states—loads XML from a string?
$xml_file = file_get_contents('test.xml');
$xml = simplexml_load_string($xml_file);
echo '<pre>';
print_r($xml);
echo '</pre>';
And the output is good when I use the XML from your post:
SimpleXMLElement Object
(
[#attributes] => Array
(
[xmlnwsa] => http://schemas.xmlsoap.org/ws/2004/08/addressing
[xmlnwsen] => http://schemas.xmlsoap.org/ws/2004/09/enumeration
[xmlnn1] => http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_SystemView
[xmlnxsi] => http://www.w3.org/2001/XMLSchema-instance
)
And so on…
And so on…
And so on…
But that said, I can recreate your error exactly if I add a space or line to the beginning of the XML file like this; note the one simple space before <?xml version="1.0" encoding="UTF-8"?>:
<?xml version="1.0" encoding="UTF-8"?>
<Envelope xmlns="http://www.w3.org/2003/05/soap-envelope" xmlnwsa="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlnwsen="http://schemas.xmlsoap.org/ws/2004/09/enumeration" xmlnn1="http://schemas.dell.com/wbem/wscim/1/cim-schema/2/DCIM_SystemView" xmlnxsi="http://www.w3.org/2001/XMLSchema-instance">
And so on…
And so on…
And so on…
And here is my error:
Warning: simplexml_load_string(): Entity: line 1: parser error : XML declaration allowed only at the start of the document in /Applications/MAMP/htdocs/test.php on line 5
Warning: simplexml_load_string(): in /Applications/MAMP/htdocs/test.php on line 5
Warning: simplexml_load_string(): ^ in /Applications/MAMP/htdocs/test.php on line 5
So hey! I know your pain!
Anyway, the quick solution I tried is to use trim on the $xml_file to get rid of extraneous white space at the beginning & end of the of the file like this:
$xml_file = file_get_contents('test.xml');
$xml = simplexml_load_string(trim($xml_file));
echo '<pre>';
print_r($xml);
echo '</pre>';
And all works great!

Related

Can't access attributes from XML response using simplexml_load_string

I'm trying to use simplexml_load_string to get the Status and Text values from the following XML response;
<?xml version="1.0" encoding="utf-16"?>
<cXML payloadID="online" xml:lang="en" timestamp="2017-12-04T15:57:47.6693296+00:00">
<Response>
<Status code="402" text="
product 325552not in customer[20690] pricelist" />
</Response>
</cXML>
In my PHP code I am getting the XML above from $reply:
$reply = curl_exec($curl);
I am then using simplexml_load_string like so:
$responseData = simplexml_load_string($reply);
echo 'Sync Order - '. $order->getIncrementId() . ' Status '. $responseData->Response->Status['code'] .' - '. $responseData->Response->Status['text'];
But this doesn't seem to get the code and text from the XML response above. Wondering if anyone has any ideas to help?
Thank you.
Note: The cXML is correct.
I've tried it with the added xml header and UTF-16 encoding bit and it fails to load with an error...
PHP Warning: simplexml_load_string(): Entity: line 1: parser error :
Document labelled UTF-16 but has UTF-8 content in
A simple but crude way round it is to change the UTF in the xml element to UTF8...
$reply = preg_replace('/(<\?xml[^?]+?)utf-16/i', '$1utf-8', $reply);
$responseData = simplexml_load_string($reply);
This then gives the output as expected...
Status 402 -
product 325552not in customer[20690] pricelist

Simplexml_load_file is working with one example, but not with other one

I made a simple website to show actually currency rates from bank website, here is xml from I got these data: http://www.nbp.pl/kursy/xml/LastA.xml. I put this into a code like that:
$xml = simplexml_load_file('http://www.nbp.pl/kursy/xml/LastA.xml');
and get it to variables like that:
<?php
for($i=0; $i<35; $i++){
$rate = (string)$xml->pozycja[$i]->kurs_sredni;
$name = (string)$xml->pozycja[$i]->nazwa_waluty;
$code = (string)$xml->pozycja[$i]->kod_waluty;
(echo here)
It works. But if I'd like to get this data from this xml, for example from yesterday: http://api.nbp.pl/api/exchangerates/tables/a/2017-04-05?format=xml, and do the same I have only errors:
Warning: simplexml_load_file(): http://api.nbp.pl/api/exchangerates/tables/a/2017-04-05:1: parser error : Start tag expected, '<' not found in [PATH] on line 13
Line 13:
$xml = simplexml_load_file('http://api.nbp.pl/api/exchangerates/tables/a/2017-04-05');
And other errors:
Warning: simplexml_load_file(): [{"table":"A","no":"067/A/NBP/2017","effectiveDate":"2017-04-05","rates":[{"curr in [PATH] on line 13
Warning: simplexml_load_file(): ^ in [PATH] on line 13
Notice: Trying to get property of non-object in [PATH] on line 18
Line 18:
$rate = (string)$xml->Rate[$i]->Mid;
What is difference between these xml's? What am I doing wrong? Could You help me?
Error 1 (invalid xml):
You're missing the ?format=xml at the end of the URL.
If you call http://api.nbp.pl/api/exchangerates/tables/a/2017-04-05 (without the format param) through a browser, it seems to default to XML automatically. If you call it through a script, it seems to default to JSON instead.
So it should work, just by changing
$xml = simplexml_load_file('http://api.nbp.pl/api/exchangerates/tables/a/2017-04-05');
to
$xml = simplexml_load_file('http://api.nbp.pl/api/exchangerates/tables/a/2017-04-05?format=xml');
Error 2 (property from non-object):
The xml looks like this:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfExchangeRatesTable xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ExchangeRatesTable>
<Table>A</Table>
<No>067/A/NBP/2017</No>
<EffectiveDate>2017-04-05</EffectiveDate>
<Rates>
<Rate>
<Currency>bat (Tajlandia)</Currency>
<Code>THB</Code>
<Mid>0.1151</Mid>
</Rate>
<Rate>
....
When you're trying to get the Rate, you're missing the first level node (ExchangeRatesTable).
Add it and it will work:
$rate = (string)$xml->ExchangeRatesTable->Rates->Rate[$i]->Mid

is it possible for HTML DOM parser to extract the line number of its source?

example
i want to extract the line number, not jut the source
for example :
foreach($html->find('u') as $element2){
echo "$element2<br />";
}
is it possible for element2 to extract the line number also?
You can use DOMNode::getLineNo() which works like this:
<?php
// XML dump for below example
$xml = <<<XML
<?xml version="1.0" encoding="utf-8"?>
<root>
<node />
</root>
XML;
// Create a new DOMDocument instance
$dom = new DOMDocument;
// Load the XML
$dom->loadXML($xml);
// Print where the line where the 'node' element was defined in
printf('The <node> tag is defined on line %d', $dom->getElementsByTagName('node')->item(0)->getLineNo());
?>
The above example will output:
The tag is defined in line 3.
FYI: Some years ago this method stopped working due to libxml2 bug but I did an online fiddle and it worked.

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.

php > SimpleXMLElement > '&' Symbol

I am having problems using the & in xml strings created by php's SimpleXMLElement. For example the following:
<?php
$xml = new SimpleXMLElement("<?xml version='1.0' encoding='UTF-8'?><links></links>");
$xml->addChild("url","https://www.somewhere.com?a=1&b=2");
echo $xml->asXML();
?>
gives me when run:
<?xml version="1.0" encoding="UTF-8"?>
<links><url>https://www.somewhere.com?a=1</url></links>
I have already tried:
...
$xml->addChild("url","https://www.somewhere.com?a=1&b=2");
...
and got:
...
<links><url>https://www.somewhere.com?a=1&b=2</url></links>
how do I get:
...
<links><url>https://www.somewhere.com?a=1&b=2</url></links>
You can't. That is illegal XML: the & character must be escaped (XML specification).

Categories