simpelXMLElement attribute namespaces - php

I looking into this problem for a few days now and need some help with it.
I want to access the namespaced attributes for the 'inhoud' element.
In this case, for example, I want the attribute value from the contentType attribute. So I want to grab the 'text/plain' value.
<inhoud p10:contentType="text/plain" p6:bestandsnaam="hallo 2.txt" xmlns:p10="http://www.w3.org/2005/05/xmlmime">aGFsbG8gZGFhciB4DQoNCg0K</inhoud>
It's prefixed with the p10 namespace.
Below the XML:
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<updateZaakdocument_Di02 xmlns="http://www.egem.nl/StUF/sector/zkn/0310">
<edcLk02 p6:entiteittype="EDC" p6:functie="update" xmlns:p6="http://www.egem.nl/StUF/StUF0301">
<parameters>
<p6:mutatiesoort>W</p6:mutatiesoort>
</parameters>
<object p6:entiteittype="EDC" p6:sleutelVerzendend="934087" p6:verwerkingssoort="W">
<inhoud p10:contentType="text/plain" p6:bestandsnaam="hallo 2.txt" xmlns:p10="http://www.w3.org/2005/05/xmlmime">aGFsbG8gZGFhciB4DQoNCg0K</inhoud>
</object>
</edcLk02>
</updateZaakdocument_Di02>
</s:Body>
</s:Envelope>
I have tried this:
<?php
$sxe = new SimpleXMLElement($xml);
$namespaces = $sxe->getNamespaces(true);
$body = $sxe->xpath('//s:Body')[0];
$inhoud = $body->updateZaakdocument_Di02->edcLk02->object->inhoud->children($namespaces["p10"]);
print_r($inhoud);
the result is:
SimpleXMLElement Object
(
[#attributes] => Array
(
[contentType] => text/plain
)
)
I tried from there:
echo (string) $inhoud >attributes($namespaces["p10"], true)->contentType;
But never get the value out of it.
Warning: Node no longer exists in the line above
Can someone point me to the right solution here?
Thanks in advance (-:

I think when your fetching the $inhoud value, your fetching the children in the p10 namespace. What instead you need to do is fetch the attributes in the p10 namespace...
$inhoud = $body->updateZaakdocument_Di02->edcLk02->object->inhoud;
print_r($inhoud);
echo "contentType=".(string)$inhoud->attributes($namespaces["p10"])->contentType;
This outputs...
SimpleXMLElement Object
(
[0] => aGFsbG8gZGFhciB4DQoNCg0K
)
contentType=text/plain
Also when using the various methods using namespaces, the second parameter is to flag that your using the prefix. When using $namespaces["p10"] this is the URI and so you should leave the second parameter out.

Related

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"/>

How to get name of very first tag of XML with php's SimpleXML?

I am parsing XML strings using simplexml_load_string(), but I noticed that i don't get the name of the very first tag.
For example, I have these two xml strings:
$s = '<?xml version="1.0" encoding="UTF-8"?>
<ParentTypeABC>
<chidren1>
<children2>1000</children2>
</chidren1>
</ParentTypeABC>
';
$t = '<?xml version="1.0" encoding="UTF-8"?>
<ParentTypeDEF>
<chidren1>
<children2>1000</children2>
</chidren1>
</ParentTypeDEF>
';
NOTICE that they are nearly identical, the only difference being that one has the first node as <ParentTypeABC> and the other as <ParentTypeDEF>
then I just convert them to SimpleXML objects:
$o = simplexml_load_string($s);
$p = simplexml_load_string($t);
but then i have two equal objects, none of them having the "top" node's name appearing, either ParentTypeABC or ParentTypeDEF (I examine the objects using print_r()):
// with top node "ParentTypeABC"
SimpleXMLElement Object
(
[chidren1] => SimpleXMLElement Object
(
[children2] => 1000
)
)
// with top node "ParentTypeDEF"
SimpleXMLElement Object
(
[chidren1] => SimpleXMLElement Object
(
[children2] => 1000
)
)
So how I am supposed to know the top node's name? If I parse unknown XMLs and I need to know what's the top node name, what can I do?
Is there an option in simplexml_load_string() I could use?
I know there are MANY ways to parse XML's with PHP, but I'd like it to be as simple as posible, and to get a simple object or array I could navigate easily.
I made a simple example here to fiddle with.
SimpleXML has a getName() method.
echo $xml->getName();
This should return the name of the respective node, no matter if root or not.
http://php.net/manual/en/simplexmlelement.getname.php

How to get value of XML tag (which contains namespace) using PHP's simplexml_load_string?

How do I get the value of "TagOne" (i.e. foo) and TagTwo (i.e. bar) from the XML below using
simplexml_load_string? I'm stumped by the namespace called "ns" in the tag.
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Body>
<ns:ExampleInterface_Output xmlns:ns="http://example.com/interfaces">
<ns:TagOne>Foo</ns:TagOne>
<ns:TagTwo>Bar</ns:TagTwo>
</ns:ExampleInterface_Output>
</SOAP-ENV:Body>
Thanks very much for your kind help!
Check this code:
<?php
$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<ns:ExampleInterface_Output xmlns:ns="http://example.com/interfaces">
<ns:TagOne>Foo</ns:TagOne>
<ns:TagTwo>Bar</ns:TagTwo>
</ns:ExampleInterface_Output>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
XML;
$xse = new SimpleXMLElement($xml);
$exampleInterface = $xse
->children('SOAP-ENV', true)
->children('ns', true);
foreach ($exampleInterface->children('ns', true) as $key => $value) {
//Do your stuff
}
Well you can declare the "ns" namespace to simplexml_load_string like this:
$xml = simplexml_load_string($string, "SimpleXMLElement", 0, "ns", TRUE);
This says that "ns" is a namespace prefix (rather than a namespace URL). See the PHP doc page for simplexml_load_string for more details.
Another problem is that the Body element has a "SOAP-ENV" prefix which is not declared anywhere in the XML, so you will get a warning about this. However, the value of $xml will become an object structured like this:
SimpleXMLElement Object (
[ExampleInterface_Output] => SimpleXMLElement Object (
[TagOne] => Foo
[TagTwo] => Bar
)
)
But, warning aside, this might be exactly what you need. If the warning is a problem, you can simply remove the "SOAP-ENV" prefix from the start and end tags of the Body element.

Parse SOAP response with PHP/xpath - Cant step further than one node

I've tried to read other tutorials & SO responses on this but I just can't seem to make it work :/
I'm able to make the SOAP request and get a response but I can't seem to parse the response.
$result = $client->GetAllAttributes($params);
And the resulting response xml is:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetAllAttributesResponse xmlns="http://connect2.askadmissions.net/webservices/">
<GetAllAttributesResult>
<result>
<code>1</code>
<ErrorMessage />
<returndata>
<attributes>
<attribute>
<type>attribute</type>
<level />
<name>text1321</name>
<mappingname><![CDATA[Extra-Curricular Interest]]></mappingname>
<datatype>Varchar2</datatype>
<size>35</size>
<validationexp />
</attribute>
<attribute> (same as above, several of these are returned</attribute>
</attributes>
</returndata>
</result>
</GetAllAttributesResult>
</GetAllAttributesResponse>
</soap:Body>
</soap:Envelope>
</xml>
I've tried
$xml = simplexml_load_string($client->__getLastResponse());
print_r($xml);
But it just prints "SimpleXMLElement Object ( ) "
I've tried
$responseXML = $client->__getLastResponse();
$xml = simplexml_load_string($responseXML);
$xml->registerXPathNamespace('soap', 'http://schemas.xmlsoap.org/soap/envelope/');
$xml->registerXPathNamespace('hob', 'http://connect2.askadmissions.net/webservices/');
$item = $xml->xpath('//hob:GetAllAttributesResult');
print_r($item);
and I get an array
Array
(
[0] => SimpleXMLElement Object
(
[0] => <result><code>1</code><ErrorMessage /><returndata><attributes><attribute> <type>attribute</type><level />
etc. (array is very long)
My problem comes when I try to step further into the tree. If I do
$item = $xml->xpath('//hob:GetAllAttributesResult/hob:result');
or
$item = $xml->xpath('//hob:GetAllAttributesResult/hob:code');
I end up with an empty array.
How do I step further into the tree?
Thank you very much for any help.
To access the element's value, you need to access the first element of the array. And you may need to cast it to string to get the string value
e.g. in your example you can do:
$item = $xml->xpath('//hob:GetAllAttributesResult/hob:result/hob:code');
print_r((string)$item[0]);

Reading a XML File in PHP

I am importing a XML file that has an amount field <amount>$10.00</amount> but when it is read in using code I got from your other posts, the value is returned as .00.
Using:
$xml = simplexml_load_file("testInput.xml");
print_r($xml);
Result:
[amount] => .00
I can't find anywhere why this is failing... Unless it has to do with the $ or period in the value field but I can't find anything about reserved characters.
I tried to duplicate your results and couldn't...
I created a file called xml_test.php:
<?php
$xml = simplexml_load_file('test_input.xml');
print_r($xml);
?>
Then built the XML (test_input.xml):
<?xml version="1.0" encoding="UTF-8"?>
<tests>
<test>
<amount>$10.00</amount>
</test>
</tests>
And this was my result in the browser:
SimpleXMLElement Object ( [test] => SimpleXMLElement Object ( [amount] => $10.00 ) )
Is there anything else going on or am I missing something? Maybe you can paste in your XML...

Categories