SimpleXML load fails to get namespaces - php

When I try to get namespaces I've got a wrong result, SimpleXML extension was loaded no errors thrown.
NOTE: On the local machine, I also cannot reproduce, but in shared host it always reproducible, is there any reasons why?
Snippet:
<?php
$xmlString = <<<DATA
<?xml version="1.0" ?>
<some version="2.0" xmlns:a="test0" xmlns:b="test1" xmlns:c="test2"></some>
DATA;
$xml = simplexml_load_string( $xmlString );
var_dump($xml->getDocNamespaces());
Result:
array(1) {
[""]=>
string(5) "test0"
}
Expected:
get
a=>test0,
b=>test1,
c=>test2
Is there any options or reasons why simplexml doesn't fetch that namespaces?
P.S.
I have tried to use simplexml_load_file, simplexml_import_dom(new DomDocument -> loadXML..), all of them return same result
P.S.2.
PHP Version 5.6.29
SimpleXML
Simplexml support enabled
Revision $Id: d7077fc935154236afb4fe70814ba358efdbdca4 $
Schema support enabled

Try this: http://codepad.org/GOggdpkJ
I have added true to getDocNamespaces(TRUE)
<?php
$xml = <<<XML
<?xml version="1.0" standalone="yes"?>
<some version="2.0" xmlns:a="test0" xmlns:b="test1" xmlns:c="test2"></some>
XML;
$sxe = new SimpleXMLElement($xml);
$namespaces = $sxe->getDocNamespaces(TRUE);
var_dump($namespaces);
?>

Related

Webhook XML always empty

I'm using recurly webhooks to update contacts, but the XML is always empty, here's what I've tried:
$xmlString = file_get_contents('php://input');
$dom = new DomDocument();
$dom->loadXML($xmlString);
however when I look into the file, it is always empty:
$rsn = $dom->getElementsByTagName('successful_payment_notification');
if($rsn->length != 0){
//.. do something
}
but I've noticed that the $dom is always empty, here's what the XML recurly sends:
<?xml version="1.0" encoding="UTF-8"?>
<successful_payment_notification>
<account>
<account_code>89728427a3caa0b21b2ds31223c0fad6f443b82</account_code>
<first_name>Michael</first_name>
<last_name>Scott</last_name>
<company_name nil="true"></company_name>
<phone nil="true"></phone>
</account>
<transaction>
<id>467fc116288ab89c8d7c954bbca565a8</id>
<invoice_id>467fc11613dcd438d4410c4ca0bc03e8</invoice_id>
<invoice_number_prefix></invoice_number_prefix>
<invoice_number type="integer">1379</invoice_number>
<test type="boolean">false</test>
<voidable type="boolean">false</voidable>
<refundable type="boolean">true</refundable>
</transaction>
</successful_payment_notification>
allow_url_fopen is On, not sure what could be causing this, I'm using AWS Lightsail and Bitnami.
I've found the answer, I changed it to this:
$xml = new SimpleXMLElement(file_get_contents('php://input'));
$data = json_decode(json_encode($xml), true);
switch ($xml->getName()) {
case "renewed_subscription_notification":
sendEmail("renewed_subscription_notification");
break;
}

How to XML to Php

How to write php so I know the link here?
There will always be different links
<response>
<redirect>
http://www.example.com/
</redirect>
<code>0</code>
<description>OK</description>
</response>
try simplexml
$xml ='<response>
<redirect>
http://www.example.com/
</redirect>
<code>0</code>
<description>OK</description>
</response>';
$xml = simplexml_load_string($xml);
echo $xml->redirect; // http://www.example.com/
simplexml_load_string
This should answer all your questions...
http://www.php.net/manual/en/function.simplexml-load-string.php
Use DOM+Xpath:
$xml = <<<'XML'
<response>
<redirect>http://www.example.com/</redirect>
<code>0</code>
<description>OK</description>
</response>
XML;
$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);
var_dump($xpath->evaluate('string(/response/redirect)'));
Output:
string(23) "http://www.example.com/"

PHP - Parse, Read XML

Not too sure what I'm doing wrong with parsing/reading an xml document.
My guess is that it's not standardized, and I'm going to need a different process to read anything from the string.
If that's the case, then I'm rather excited to learn how someone would read the xml.
Here's what I've got, and what I'm doing.
example.xml
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="someurl.php"?>
<response>
<status>Error</status>
<error>The error message I need to extract, if the status says Error</error>
</response>
read_xml.php
<?php
$content = 'example.xml';
$string = file_get_contents($content);
$xml = simplexml_load_string($string);
print_r($xml);
?>
I'm getting no result back from the print_r.
I switched the xml to something more standard, like:
<?xml version="1.0" encoding="ISO-8859-1"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</note>
...and it worked fine. So I'm sure it's due to a non-standard format, passed back from the source I'm getting it from.
How would I extract the <status> and <error> tags?
Tek has a good answer, but if you want to use SimpleXML, you can try something like this:
<?php
$xml = simplexml_load_file('example.xml');
echo $xml->asXML(); // this will print the whole string
echo $xml->status; // print status
echo $xml->error; // print error
?>
EDIT: If you have multiple <status> and <error> tags in your XML, have a look at this:
$xml = simplexml_load_file('example.xml');
foreach($xml->status as $status){
echo $status;
}
foreach($xml->error as $error){
echo $error;
}
I'm assuming <response> is your root. If it isn't, try $xml->response->status and $xml->response->error.
I prefer to use PHP's DOMDocument class better.
Try something like this:
<?php
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="someurl.php"?>
<response>
<status>Error</status>
<error>The error message I need to extract, if the status says Error</error>
</response>';
$dom = new DOMDocument();
$dom->loadXML($xml);
$statuses = $dom->getElementsByTagName('status');
foreach ($statuses as $status) {
echo "The status tag says: " . $status->nodeValue, PHP_EOL;
}
?>
Demo: http://codepad.viper-7.com/mID6Hp

Why can't I embed php in the xml file? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Escaping <? on php shorthand enabled server when using require
What I want is that when I make a Ajax get request to domain/xml.php. It return a XML file, so I can use httpRequest.responseXML to parse the XML file.
what I did is:
<?php
$name = 'Just a tester';
?>
<?xml version='1.0' ?>
<name><?php echo $name ?></name>
But the parser gives me an error of the line <?xml version='1.0' ?>, I thought it might be syntax conflict with the php delimiter <?php.
How can I request a url and get xml generated by php?
You have shorttags enabled. This is the default, and as of PHP 5.4, tags are supported everywhere, regardless of shorttags settings.
The problem is that <?xml version='1.0' ?> starts and ends with <? ?>, just like PHP with shorttags.
To get round this use:
echo "<?xml version='1.0' ?>";
on that line.
Why are you trying to embed PHP variables into XML instead of generating the XML with PHP?
Example (xml.php):
<?php
header('Content-type: text/xml; charset=utf-8');
//Your Data
$persons = array(array('name'=>'bob','age'=>20,'sex'=>'M'),
array('name'=>'steve','age'=>26,'sex'=>'M'),
array('name'=>'jen','age'=>33,'sex'=>'F'),
);
$xml = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><persons/>');
foreach ($persons as $person) {
$node = $xml->addChild('person');
foreach($person as $key=>$value){
$node->addChild($key, $value);
}
}
//DOMDocument to format code output
$dom = new DOMDocument('1.0');
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($xml->asXML());
echo $dom->saveXML();
/* OUTPUT
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person>
<name>bob</name>
<age>20</age>
<sex>M</sex>
</person>
<person>
<name>steve</name>
<age>26</age>
<sex>M</sex>
</person>
<person>
<name>jen</name>
<age>33</age>
<sex>F</sex>
</person>
</persons>
*/
?>
You could try:
<?php
header('Content-type: text/xml; charset=utf-8');
$name = 'Just a tester';
echo "<?xml version='1.0' ?>";
?>
<name><?php echo $name; ?></name>
Change
echo "<?xml...?>";
to
echo '<'."?...?".'>';
Or use Lawerence solution
You should set up your webserver to process not only PHP but XML files also through the PHP preprocessor.
You have short tags enabled. These should be disabled in your php.ini, search for "short_open_tag" and "asp_tag".
If you have an earlier version than PHP 5.3.0 this will probably work (if you only want this for the current document):
<?php ini_set('short_open_tag', 0); ?>

Adding node using PHP's SimpleXML to XML with namespaces

<?xml version="1.0" encoding="ISO-8859-2"?>
<!DOCTYPE pasaz:Envelope SYSTEM "loadOffers.dtd">
<pasaz:Envelope xmlns:pasaz="http://schemas.xmlsoap.org/soap/envelope/">
<pasaz:Body>
<loadOffers xmlns="urn:ExportB2B">
<offers />
</loadOffers>
</pasaz:Body>
</pasaz:Envelope>
I've to add some child nodes to "offers" node and I'm using SimpleXML.
The PHP code: $offer = $xml->offers->addChild('offer') returns an error.
It's all wrong because I've got problem with handling namespaces in SimpleXML! Please help!
E.g. by using xpath the get the target/parent element.
<?php
$envelope = new SimpleXMLElement('<?xml version="1.0" encoding="ISO-8859-2"?>
<!DOCTYPE pasaz:Envelope SYSTEM "loadOffers.dtd">
<pasaz:Envelope xmlns:pasaz="http://schemas.xmlsoap.org/soap/envelope/">
<pasaz:Body>
<loadOffers xmlns="urn:ExportB2B">
<offers />
</loadOffers>
</pasaz:Body>
</pasaz:Envelope>');
$envelope->registerXPathNamespace('pasaz', 'http://schemas.xmlsoap.org/soap/envelope/');
$envelope->registerXPathNamespace('b2b', 'urn:ExportB2B');
$ns = $envelope->xpath('//pasaz:Body/b2b:loadOffers/b2b:offers');
if ( 0<count($ns) ) {
$offers = $ns[0];
$offers->a = 'abc';
$offers->x = 'xyz';
}
echo $envelope->asXml();
prints
<?xml version="1.0" encoding="ISO-8859-2"?>
<!DOCTYPE pasaz:Envelope SYSTEM "loadOffers.dtd">
<pasaz:Envelope xmlns:pasaz="http://schemas.xmlsoap.org/soap/envelope/">
<pasaz:Body>
<loadOffers xmlns="urn:ExportB2B">
<offers><a>abc</a><x>xyz</x></offers>
</loadOffers>
</pasaz:Body>
</pasaz:Envelope>

Categories