Convert XML File to Json fail - php

I don't understand what it's wrong on this code for read a XML File version 1.0 and convert to json
$xml = simplexml_load_file('/Volumes/ABKDatos/warehouse/tmp/1.xml');
libxml_use_internal_errors(true);
if ($xml === false)
{
echo "Error cargando XML".PHP_EOL;
foreach(libxml_get_errors() as $error) {
echo "\t", $error->message;
}
}
var_dump($xml->count());
$json = json_encode($xml);
$array = json_decode($json,TRUE);
var_dump($array)
show
int(0)
array(0) {
}
XML File
<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet type="text/xsl" href="/3.2/style/exchange.xsl"?>
<ops:world-patent-data xmlns="http://www.epo.org/exchange" xmlns:ops="http://ops.epo.org" xmlns:xlink="http://www.w3.org/1999/xlink">
<ops:biblio-search total-result-count="185">
<ops:query syntax="CQL">ti all "organic plastic" AND pd within "20070101,20170610"</ops:query>
<ops:range begin="1" end="100"/>
<ops:search-result>
<ops:publication-reference system="ops.epo.org" family-id="58738760">
<document-id document-id-type="docdb">
<country>US</country>
<doc-number>9665818</doc-number>
<kind>B1</kind>
</document-id>
</ops:publication-reference>
<ops:publication-reference system="ops.epo.org" family-id="53524784">
<document-id document-id-type="docdb">
<country>US</country>
<doc-number>2017121644</doc-number>
<kind>A1</kind>
</document-id>
</ops:publication-reference>
...
</ops:search-result>
</ops:biblio-search>
</ops:world-patent-data>

Related

PHP updating xml CDATA fields with DOMdocument

I have the following XML data:
<?xml version="1.0" encoding="utf-8"?>
<source>
<publisher>some-data</publisher>
<publisherurl>some-data</publisherurl>
<lastBuildDate>a-date</lastBuildDate>
<element>
<sub-element><![CDATA[some-data]]></sub-element>
</element>
</source>
I'm trying to use PHP's built in DOMdocument parser to update the text inside sub-element.
I've tried:
$dom=new DOMDocument();
$dom->load("document.xml");
$ele=$root->getElementsByTagName('element');
foreach ($ele as $e) {
$e->getElementsByTagName('sub-element')->item(0)->nodeValue = "new val";
}
this kind of works but it removes the CDATA and just replaces it with new-val. I want to preserve the CDATA field so I tried the following:
$dom=new DOMDocument();
$dom->load("document.xml");
$ele=$root->getElementsByTagName('element');
foreach ($ele as $e) {
$sub=$e->getElementsByTagName('sub-element');
foreach($sub->childNodes as $child) {
if ($child->nodeType == XML_CDATA_SECTION_NODE) {
$child->nodeValue = 'new-val';
}
}
}
This seems like it should work but PHP returns the following Notice
Undefined property: DOMNodeList::$childNodes
Feel like I'm on the right path but I just can't figure out what I'm doing wrong here. Does anyone know how to fix?
My end goal output is:
<?xml version="1.0" encoding="utf-8"?>
<source>
<publisher>some-data</publisher>
<publisherurl>some-data</publisherurl>
<lastBuildDate>a-date</lastBuildDate>
<element>
<sub-element><![CDATA[new-val]]></sub-element>
</element>
</source>
You need to compare against firstChild
$xml = '<?xml version="1.0" encoding="utf-8"?>
<source>
<publisher>some-data</publisher>
<publisherurl>some-data</publisherurl>
<lastBuildDate>a-date</lastBuildDate>
<element>
<sub-element><![CDATA[some-data]]></sub-element>
</element>
<element>
<sub-element>some-other-data</sub-element>
</element>
</source>';
$dom = new DOMDocument();
$dom->loadXML($xml);
$ele=$dom->getElementsByTagName('element');
foreach ($ele as $e) {
$item = $e->getElementsByTagName('sub-element')->item(0);
if($item->firstChild->nodeType == XML_CDATA_SECTION_NODE) { //<------
//it's CDATA do whatever
$item->firstChild->nodeValue = "new val";
} else {
//it's not , do something else
$item->nodeValue = "new val";
}
}
echo "<pre>";
print_r(htmlentities($dom->saveXML()));
echo "</pre>";
Output:
<?xml version="1.0" encoding="utf-8"?>
<source>
<publisher>some-data</publisher>
<publisherurl>some-data</publisherurl>
<lastBuildDate>a-date</lastBuildDate>
<element>
<sub-element><![CDATA[new val]]></sub-element>
</element>
<element>
<sub-element>new val</sub-element>
</element>
</source>
PS: if you don't have to make a distinction between CDATA or not, just use firstChild
foreach ($ele as $e) {
$item = $e->getElementsByTagName('sub-element')->item(0);
$item->firstChild->nodeValue = "new val";
}

simplexml_load_string cannot load XML / No error / result not === false

XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<result sync="false" version="2">
<action>start-subscription</action>
<action_result>
<code>103</code>
<detail>1 missing parameter</detail>
<missing_parameters>
<missing_parameter>
<key>operator</key>
</missing_parameter>
</missing_parameters>
<status>1</status>
</action_result>
<custom_parameters>
<custom_parameter>
<key>cp_REF</key>
<value>simpleLPADULTCHSMSV2___WoopGang------___Adjomo___external___paid___android___CH___WIFI___locale=fr_FR</value>
</custom_parameter>
</custom_parameters>
<customer>
<country>CH</country>
<language>en</language>
</customer>
<payment_parameters>
<channel>web</channel>
<method>OPERATOR</method>
<order>90330</order>
</payment_parameters>
<transactions>
<transaction>
<id>1308636894</id>
<status>-1</status>
</transaction>
</transactions>
<request_id>1591621_t593818e0f3913</request_id>
<reference>09045c8e-9ec1-4306-8699-5ac5306983b2</reference>
</result>
PHP:
$xml = file_get_contents("php://input");
$datas = array();
parse_str($xml, $datas);
$data = $datas['data'];
libxml_use_internal_errors(true);
$xml = simplexml_load_string($data);
if($xml === false){
foreach(libxml_get_errors() as $error) {
$this->_logCall(self::LOG_DIMOCO, $error->message,"--");
}
}else{
$this->_logCall(self::LOG_DIMOCO, 'loaded simpleXML '.print_r($xml), ' --');
}
Running that ends in the last ELSE and the result is "1"
Any idea what I'm doing wrong ?
I have to add some text because apparently its mostly code and not understandable. Now ? Now ? Now ? Now ?
print_r() (by default) doesn't return output, it prints it -- so you can't use it in a string context. If you want to do that, you can pass a truthy value as the second parameter to have it return the output instead of printing it:
$this->_logCall(self::LOG_DIMOCO, 'loaded simpleXML '.print_r($xml, true), ' --');

Parsing an XML Caldav request in php

I'm trying to parse a request sent by ThunderBird to my CalDAV Server and from an example taken from stackoverflow with an XML like :
<?xml version="1.0" encoding="ISO-8859-1"?>
<products>
<last_updated>2009-11-30 13:52:40</last_updated>
<product>
<element_1>foo</element_1>
<element_2>foo</element_2>
<element_3>foo</element_3>
<element_4>foo</element_4>
</product>
</products>
Using the function :
$XMLr = new XMLReader;
$XMLr->open('test.xml');
$doc = new DOMDocument;
// move to the first <product /> node
while ($XMLr->read() && $XMLr->name !== 'product');
// now that we're at the right depth, hop to the next <product/> until the end of the tree
$node = simplexml_import_dom($doc->importNode($XMLr->expand(), true));
// now you can use $node without going insane about parsing
$children = $node->children();
foreach($children as $child)
{
echo $child->getName();
echo "\n";
}
I get the answer "element_1 element_2 element_3 element_4 ", but if I use the same function on my request :
<?xml version="1.0" encoding="UTF-8"?>
<D:propfind xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<D:resourcetype/>
<D:owner/>
<D:current-user-principal/>
<D:supported-report-set/>
<C:supported-calendar-component-set/>
<CS:getctag/>
</D:prop>
</D:propfind>
Replacing $XMLr->name !== 'product' by $XMLr->name !== 'D:prop' I get a white screen...
What do I do wrong ?
How can I get the answer "ressourcetype owner current-user-principal etc ..." ?
I try with XMLReader and simplexml_import_dom without success but in opposite, with DomDocument you can do it:
// Just for display test results
$break_line = '<br>';
if (php_sapi_name() === 'cli') {
$break_line = "\n";
}
$xml = '<?xml version="1.0" encoding="UTF-8"?>
<D:propfind xmlns:D="DAV:" xmlns:CS="http://calendarserver.org/ns/" xmlns:C="urn:ietf:params:xml:ns:caldav">
<D:prop>
<D:resourcetype/>
<D:owner/>
<D:current-user-principal/>
<D:supported-report-set/>
<C:supported-calendar-component-set/>
<CS:getctag/>
</D:prop>
</D:propfind>';
$xml_document = new DomDocument(); // http://fr2.php.net/manual/fr/class.domdocument.php
$xml_document->loadXML($xml); // Or load file with $xml_document->load('test.xml);
$elements = $xml_document->getElementsByTagName('prop');
// $elements is a DOMNodeList object: http://fr2.php.net/manual/fr/class.domnodelist.php
foreach($elements as $element) {
// $element is a DOMElement object: http://fr2.php.net/manual/fr/class.domelement.php
$childs = $element->childNodes;
// $childs is DOMNodeList
foreach ($childs as $child) {
// $element is a DOMElement object
if ($child instanceof DOMElement) {
echo $child->nodeName . $break_line;
}
}
}
White screen normally means error.
Put error_reporting on E_ALL
error_reporting('E_ALL');

Error while Getting data from an xml file

I have written the following code to understand how php can be used to get and write data to xml files:
<?php
if (file_exists('/requests.xml')) {
$xml = simplexml_load_file('requests.xml');
foreach($xml->data->requests->request as $req)
{
print "Loop entered";
print $req->ip;
print $req->timelast;
}
}
?>
The xml file requests.xml follows:
<?xml version="1.0" encoding="utf-8"?>
<data>
<requests>
<request>
<ip>6.6.6.6</ip>
<timelast>2014-05-30 11:38:23</timelast>
</request>
</requests>
</data>
The problem is that when the script is run, it does not display anything in the browser. In fact it does not enter the loop.
I'm definitely missing something basic.
$xml will take your default node auto so no need to fetch result with data try
foreach($xml->requests->request as $req)
also change
if (file_exists('/requests.xml')) {
to
if (file_exists('requests.xml')) { // if same dir
i have tried like:-
$xml ='<?xml version="1.0" encoding="utf-8"?>
<data>
<requests>
<request>
<ip>6.6.6.6</ip>
<timelast>2014-05-30 11:38:23</timelast>
</request>
</requests>
</data>';
$xml = simplexml_load_string($xml);
foreach($xml->requests->request as $req)
{
print "Loop entered";
print $req->ip;
print $req->timelast;
}
output :- Loop entered6.6.6.62014-05-30 11:38:23
<?php
try
{
$feed = new SimpleXMLElement('requests.xml', null, true);
}
catch(Exception $e)
{
echo $e->getMessage();
exit;
}
foreach($feed->member as $property)
{
echo $property->id;
echo $property->lastName;
}
?>
XML :
1
MSDWEr

decode XML with SimpleXMLElement

When trying to read the file here nothing is returned...
What am I doing wrong?
beginning of the XML file
<?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ccts="urn:oasis:names:specification:ubl:schema:xsd:CoreComponentParameters-2" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:ns7="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:sdt="urn:oasis:names:specification:ubl:schema:xsd:SpecializedDatatypes-2" xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2"><cec:UBLExtensions xmlns:cec="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"><cec:UBLExtension><cec:ExtensionURI>urn:oasis:names:specification:ubl:profile:dsig:signature</cec:ExtensionURI><cec:ExtensionContent><sig:UBLDocumentSignatures xmlns:sig="urn:oasis:names:specification:ubl:schema:xsd:CommonSignatureComponents-2"><sig:SignatureInformation><cbc:ID>urn:oasis:names:specification:ubl:signatures:1</cbc:ID><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/TR/1999/REC-xpath-19991116"><XPath>count(ancestor-or-self::sig:UBLDocumentSignatures | here()/ancestor::sig:UBLDocumentSignatures[1]) > count(ancestor-or-self::sig:UBLDocumentSignatures)</XPath></Transform></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><DigestValue>Agc2+1rOPYaPgixs6RTiLZzoj4H5/96eA8nv6dlU6yA=</DigestValue></Reference></SignedInfo><SignatureValue>Mp3ziREgnkg0jU+l+Jl+4viQKFTwMnY7DTFlK1jzbVZjV7r9nmnePSrr/nvdJWZt1bheKMiEMYBi
ax7bcGUZYj4QFdO7z8W+MvsxGGG0TswRBay51J+ja08rtob/YQ5Z+Yc25PEko3nuePItYPVAKsXW
E51EAWgVd/kXpRF6xrQ=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>qjPnoh/BgvN22UWUVcwVYr9xWj49ffp2obvmR5WttIJssS5ZbCYOxjIjO3gIcNAu6NLFn5gpsp95
FPNY1JDGII1qPnp9zyI6HKyA3yb5Vq9ONm2cLRfOz2zrvPdG+38ZLMzHe1rLALXEoIqfJWWt3u2B
UvWP+h5ZYzm8px1gmJM=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue><X509Data><X509Certificate>MIICATCCAWoCCQCo1AOqHHrvcDANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJBVTETMBEGA1UE
CBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMB4XDTEwMDQw
OTA5MTkyN1oXDTI5MTIyNTA5MTkyN1owRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3Rh
dGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCBnzANBgkqhkiG9w0BAQEFAAOB
jQAwgYkCgYEAqjPnoh/BgvN22UWUVcwVYr9xWj49ffp2obvmR5WttIJssS5ZbCYOxjIjO3gIcNAu
6NLFn5gpsp95FPNY1JDGII1qPnp9zyI6HKyA3yb5Vq9ONm2cLRfOz2zrvPdG+38ZLMzHe1rLALXE
oIqfJWWt3u2BUvWP+h5ZYzm8px1gmJMCAwEAATANBgkqhkiG9w0BAQUFAAOBgQARLOs0egYgj7q7
mN0uthdbzAEg75Ssgh4JuOJ3iXI/sbqAIQ9uwsLodo+Fkpb5AiLlNFu7mCZXG/SzAAO3ZBLAWy4S
KsXANu2/s6U5ClYd93HoZwzXobKb+2+aMf7KiAg1wHPUcyKx2c5nplgqQ7Hwldk9S9yzaRsYEGWT
+xpSUA==</X509Certificate></X509Data></KeyInfo></Signature></sig:SignatureInformation></sig:UBLDocumentSignatures></cec:ExtensionContent></cec:UBLExtension></cec:UBLExtensions>
<cbc:UBLVersionID>2.0</cbc:UBLVersionID>
<cbc:CustomizationID>OIOUBL-2.01</cbc:CustomizationID>
<cbc:ProfileID schemeAgencyID="320" schemeID="urn:oioubl:id:profileid-1.2">urn:www.nesubl.eu:profiles:profile5:ver2.0</cbc:ProfileID>
<cbc:ID>10</cbc:ID>
<cbc:IssueDate>2011-11-15</cbc:IssueDate>
<cbc:InvoiceTypeCode listAgencyID="320" listID="urn:oioubl:codelist:invoicetypecode-1.1">380</cbc:InvoiceTypeCode>
code
$file = 'tradeshift_invoice.xml';
if(is_file($file)){
echo 'file exists<br><br>';
}
else{
echo 'file does not exists<br><br>';
}
$xml = simplexml_load_file($file);
//$xml = new SimpleXMLElement(simplexml_load_file($file), 0, true);
echo 'count '.$xml->count().'<br><br>';
foreach($xml->children() as $child){
print_r($child);
}
output
file exists
count 0
new SimpleXMLElement is only for string data, not for a file. You want to use:
simplexml_load_file($file)
instead...
Look for it under: http://www.php.net/manual/function.simplexml-load-file.php

Categories