php > SimpleXMLElement > '&' Symbol - php

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).

Related

PHP get specific data from xml file

This is XML file.
<?xml version="1.0" encoding="utf-8"?>
<UW xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/XMLSchema.xsd">
<UWdata>
<List>
<IdProduct>1</IdProduct>
<ProductName>product</ProductName>
<ProductNameDE>product</ProductNameDE>
<ProductNameEN>product</ProductNameEN>
<Uf>1</Uf>
<PSIg>1</PSIg>
<Ug>1</Ug>
</List>
</UWdata>
</UW>
$lines_array=file($url);
$lines_string=implode('',$lines_array);
$xml=simplexml_load_string($lines_string) or die("Error: Cannot create object");
I try with this
echo $xml->UWdata[1]->ProductName;
But it doesn't return anything.I want to return Product name.
Sample code, Use simplexml_load_string
<?php
$a = '<?xml version="1.0" encoding="utf-8"?>
<UW xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/XMLSchema.xsd">
<UWdata>
<List>
<IdProduct>1</IdProduct>
<ProductName>product</ProductName>
<ProductNameDE>product</ProductNameDE>
<ProductNameEN>product</ProductNameEN>
<Uf>1</Uf>
<PSIg>1</PSIg>
<Ug>1</Ug>
</List>
</UWdata>
</UW>';
$xml=simplexml_load_string($a) or die("Error: Cannot create object");
echo ($xml->UWdata->List->ProductName);
?>
When you load the xml file using the php simplexml_load_file function to a variable. The veritable becomes an object.
<?php
$xml=simplexml_load_file("/path/to/the/file.xml");
?>
So, in your case, the $xml variable becomes a multi-level object where every elements of xml file are key of the object. Like: UWdata.
So, as $xml is a multi-level object, to access the element under UWdata, under List under ProductName, you have to code like bellow.
echo $xml->UWdata->List->ProductName."<br>";
Here,
UWdata is the key of $xml object.
List is the key of UWdata.
ProductName is the key of List.
Finally, you will get the value of key element ProductName = product
I modified your script and put the xml in an external file called testxml.xml, as it should be. Always separate the function and the data it's supposed to handle. I used your xml like this:
<?xml version="1.0" encoding="utf-8"?>
<UW xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://tempuri.org/XMLSchema.xsd">
<UWdata>
<List>
<IdProduct>1</IdProduct>
<ProductName>productTEST</ProductName>
<ProductNameDE>product</ProductNameDE>
<ProductNameEN>product</ProductNameEN>
<Uf>1</Uf>
<PSIg>1</PSIg>
<Ug>1</Ug>
</List>
</UWdata>
</UW>
And with the following script it returns productTEST only.
$xmlstr = file_get_contents('./testxml.xml');
$xml = simplexml_load_string($xmlstr);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
echo $array['UWdata']['List']['ProductName'];
Hope this helps.
//edit:
While I do not know your project, you might want to take a foreach-approach if it is possible for your xml to contain more than one List element

PHP SimpleXMLElement addAttribute namespaces syntax

I'm working with SimpleXMLElement for the first time and need to generate a line in my XML as follows:
<Product xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
I haven't used addAttribute with namespaces before and can't get the correct syntax working here - I've started with this:
$node = new SimpleXMLElement('< Product ></Product >');
$node->addAttribute("xmlns:", "xsd:", 'http://www.w3.org/2001/XMLSchema-instance');
but can't work out how to correct this for the appropriate syntax to generate the desired output?
solution 1: add a prefix to the prefix
<?php
$node = new SimpleXMLElement('<Product/>');
$node->addAttribute("xmlns:xmlns:xsi", 'http://www.w3.org/2001/XMLSchema-instance');
$node->addAttribute("xmlns:xmlns:xsd", 'http://www.w3.org/2001/XMLSchema');
echo $node->asXML();
output:
<?xml version="1.0"?>
<Product xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"/>
note: this is a workaround and actually doesn't set the namespace for the attribute, but just quite enough if you are going to echo / save to file the result
solution 2: put namespace directly in the SimpleXMLElement constructor
<?php
$node = new SimpleXMLElement('<Product xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"/>');
echo $node->asXML();
output is the same as in solution 1
solution 3 (adds additional attribute)
<?php
$node = new SimpleXMLElement('<Product/>');
$node->addAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance", "xmlns");
$node->addAttribute("xmlns:xsd", 'http://www.w3.org/2001/XMLSchema', "xmlns");
echo $node->asXML();
output adds additional xmlns:xmlns="xmlns"
<?xml version="1.0"?>
<Product xmlns:xmlns="xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"/>

convert xml to string php with tag

I am trying to convert the following line to a string using
$xml_post_string = '<?xml version="1.0" encoding="UTF-8"?>';
However, echo $xml_post_string does not print anything, but when i remove the <? from the string, it works. How can I get through this issue?
You can use html tag <xmp> for that purpose, it renders a container content "as is". But I must note that it's included in the list of "obsolete" elements.
$xml_post_string = '<?xml version="1.0" encoding="UTF-8"?>';
echo "<xmp>".($xml_post_string)."</xmp>";
// the output:
<?xml version="1.0" encoding="UTF-8"?>

SimpleXMLElement creating two XML Tags

I'm building xml with the SimpleXMLElement Object from PHP.
While doing so I encountered the following problem, which i can't solve:
I'm generating the root xml element like this:
$xml = new SimpleXMLElement("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
But i get a 2 XML headers when i do echo $xml->asXML(); like this:
<?xml version="1.0"?>
<xml version="1.0" encoding="UTF-8"></xml>
Which is obvioulsy wrong. But how can i fix this so i only get the
<xml version="1.0" encoding="UTF-8">
part?
You must also supply the surrounding tag.
For example:
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8" ?> <BASETAG />');

Issues loading XML file data into a PHP object

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!

Categories