XML Changing value of namespace property - php

I need to change a value of a nested namespace property within a XML document before I submit it to an EPP service.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd">
<command>
<info>
<host:info xmlns:host="urn:ietf:params:xml:ns:host-1.0" xsi:schemaLocation="urn:ietf:params:xml:ns:host-1.0 host-1.0.xsd">
<host:name>ns1.example.test.example.com</host:name>
</host:info>
</info>
<clTRID>NORID-14373-1207137695427775</clTRID>
</command>
</epp>
In the above XML, I need to change the host:name elements value. I am using PHP simplexml_load_string to first modify the values from the XML schema as shown below.
$xml = simplexml_load_string(file_get_contents($fn));
$xml->command->clTRID = GUID(); // This works perfectly
$xml->command->info->name = 'somename'; // Does not work :)
What is the correct way to do this?

Use the following code
Note I am echoing the data for your reference as how to use it
echo $xml->command->info->children('host', true)->info->name;
Total simple code which I tried
$xmls = '<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd">
<command>
<info>
<host:info xmlns:host="urn:ietf:params:xml:ns:host-1.0" xsi:schemaLocation="urn:ietf:params:xml:ns:host-1.0 host-1.0.xsd">
<host:name>ns1.example.test.example.com</host:name>
</host:info>
</info>
<clTRID>NORID-14373-1207137695427775</clTRID>
</command>
</epp>';
$xml = simplexml_load_string($xmls);
$xml->command->clTRID = 'something'; // This works perfectly
echo $xml->command->info->children('host', true)->info->name;
$xml->command->info->children('host', true)->info->name = 'some new name';
echo $xml->command->info->children('host', true)->info->name;

Related

How to parse top level XML element php [duplicate]

Using simplexml_load_string() how do I get "ForgotPassword" from the following XML?
<?xml version="1.0" encoding="utf-8"?>
<ForgotPassword>
<version>1.0</version>
<authentication>
<login>username</login>
<apikey>login</apikey>
</authentication>
<parameters>
<emailAddress>joesmith#example.com</emailAddress>
</parameters>
</ForgotPassword>
Are you wanting to get the name of the root node?
$xml = simplexml_load_string($str);
echo $xml->getName();

php xml schema formatting

I have a php page what post's a xml to Heartinternet API and after a long time I have got it to work but now I cant find away to only pull only one part out of the replyed XML
$some_xml = '<?xml version="1.0"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:package="http://www.heartinternet.co.uk/whapi/package-2.2">
<command>
<info>
<package:info>
<package:id>171371a16973b1bf</package:id>
</package:info>
</info>
<extension>
<ext-package:preAuthenticate xmlns:ext-package="http://www.heartinternet.co.uk/whapi/ext-package-2.2"/>
</extension>
<clTRID>fac89208bea460fa3fef11b22a519cce</clTRID>
</command>
</epp>';
This is the code what is posted to the API. Full code can been seen here.
This is what I get back and can't figure out how to pull one line from the reply.
<?xml version='1.0'?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:ext-package="http://www.heartinternet.co.uk/whapi/ext-package-2.2">
<response>
<result code='1000'>
<msg>Command completed successfully</msg>
</result>
<resData>
<ext-package:redirectURL>http://bobcp.example.org/sso.cgi?session=LUB9UNbw6jTW</ext-package:redirectURL>
</resData>
<trID>
<clTRID>fac89208bea460fa3fef11b22a519cce</clTRID>
<svTRID>test-19272326601ef4c3bf6b64730d09c6cf</svTRID>
</trID>
</response>
</epp>
The one line I need to show is ext-package:redirectURL.
If anyone could help me or point me in the right direction to find how to sort this I would be grateful!
You can get the redirect url by registering the namespace urn:ietf:params:xml:ns:epp-1.0 and then you could use an xpath expression for example. In this case, I have chosen u as the prefix.
/u:epp/u:response/u:resData/ext-package:redirectURL
Using SimpleXML with your returned xml:
The response xml from the comments is slightly different. This is the updated code:
$returned_xml->registerXPathNamespace('u', 'urn:ietf:params:xml:ns:epp-1.0');
$returned_xml->registerXPathNamespace('ext-package', 'http://www.heartinternet.co.uk/whapi/ext-package-2.2');
$redirectUrl = $returned_xml->xpath('/u:epp/u:response/u:resData/ext-package:redirectURL');
echo $redirectUrl[0];
Or with DOMDocument:
$doc = new DOMDocument();
$doc->loadXML(file_get_contents("https://custom-hosting.co.uk/source/test.php"));
$xpath = new DOMXpath($doc);
$xpath->registerNamespace('u', 'urn:ietf:params:xml:ns:epp-1.0');
$xpath->registerNamespace('ext-package', 'http://www.heartinternet.co.uk/whapi/ext-package-2.2');
$redirectUrl = $xpath->query('/u:epp/u:response/u:resData/ext-package:redirectURL')->item(0)->nodeValue;
echo $redirectUrl;
That will give you for example:
http://bobcp.example.org/sso.cgi?session=LUB9UNbw6jTW
<?xml version='1.0'?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0" xmlns:ext-package="http://www.heartinternet.co.uk/whapi/ext-package-2.2">
<response>
<result code='1000'>
<msg>Command completed successfully</msg>
</result>
<resData>
<ext-package:redirectURL>http://bobcp.example.org/sso.cgi?session=LUB9UNbw6jTW</ext-package:redirectURL>
</resData>
<trID>
<clTRID>fac89208bea460fa3fef11b22a519cce</clTRID>
<svTRID>test-19272326601ef4c3bf6b64730d09c6cf</svTRID>
</trID>
</response>
</epp>
that is what i get sent back from the API its not in my test page at all
Full page source
if i add
$xml = simplexml_load_string($returned_xml);
$xml->registerXPathNamespace('u', 'urn:ietf:params:xml:ns:epp-1.0');
$redirectUrl = $xml->xpath('/u:epp/u:response/u:resData/ext-package:redirectURL');
echo $redirectUrl[0];
to the page i just get
XML Parsing Error: no element found
Location: https://custom-hosting.co.uk/
Line Number 1, Column 1:

How to parse XML-file to array and retrieve all children of an child with specific attribute in PHP?

my XML-file is as follows: agents.xml
<?xml version="1.0" encoding="UTF-8"?>
<agents>
<agent id="1">
<aname>pi1</aname>
<alive>0</alive>
<scenarios>1,2,3</scenarios>
</agent>
<agent id="2">
<aname>pi2</aname>
<alive>1</alive>
<scenarios>4,5,6</scenarios>
</agent>
</agents>
I want to retrieve all child elements of an agent, selected by attribute value "id". I tried the following, passing a the variable "id" to the script:
$agents_xml = simplexml_load_file("/<path_to>/agents.xml");
$json = json_encode($agents_xml);
$array = json_decode($json,TRUE);
//decrement id for correct index
$id=$id-1;
//I want to return in JSON format
$testarr=json_encode($array['agent'][$id]);
echo $testarr;
When "id" has value 1, i got this:
{"#attributes":{"id":"1"},"aname":"pi1","alive":"0","scenarios":"1,2,3"}
But i know, if the XML is disordered like:
<?xml version="1.0" encoding="UTF-8"?>
<agents>
<agent id="2">
<aname>pi2</aname>
<alive>1</alive>
<scenarios>4,5,6</scenarios>
</agent>
<agent id="1">
<aname>pi1</aname>
<alive>0</alive>
<scenarios>1,2,3</scenarios>
</agent>
</agents>
This is not very reliable.
Thanks for any idea!
Try
$str = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<agents>
<agent id="1">
<aname>pi1</aname>
<alive>0</alive>
<scenarios>1,2,3</scenarios>
</agent>
<agent id="2">
<aname>pi2</aname>
<alive>1</alive>
<scenarios>4,5,6</scenarios>
</agent>
</agents>
XML;
$xml = new SimpleXMLElement($str);
foreach($xml->agent as $agent)
{
var_dump($agent);
echo "<hr>";
}

Pass data from Array to XML and save to variable

I have an array $data = array ( 'name' => 'makis', 'pw' => 'sovara') and i need to fill in an XML file using those values and then save that XML into a temporary variable.
For example the XML is
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:ietf:params:xml:ns:epp-1.0
epp-1.0.xsd">
<command>
<login>
<clID>['name']</clID>
<pw>['pw']</pw>
<options>
<version>1.0</version>
<lang>en</lang>
</options>
<svcs>
<objURI>urn:ietf:params:xml:ns:host-1.0</objURI>
<objURI>urn:ietf:params:xml:ns:contact-1.0</objURI>
<objURI>urn:ietf:params:xml:ns:domain-1.0</objURI>
</svcs>
</login>
<clTRID>nick-12345</clTRID>
</command>
</epp>
How can i do that in php?
You can use simplexml:
$xml = simplexml_load_file('path/to/file');
// $xml is object that represents <epp> root node
$xml->command->login->clID = $data['name'];
$xml->command->login->pw = $data['pw'];
$xml->asXML('new/file/path'); // save to new file

Change xml file string value from another xml file's content in php

My question may be easy. But I've never interested with XML. So it is not understandable for me. There is an installation program and it's language files are xml format. Turkish file is very narrow that other languages. So I want to import "turkish.xml" into "general.xml". In "general.xml" file, if there are same nodes, nodes value will be changed. If not, keep it same. For example this is content of my turkish.xml.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DICTIONARY type="singlelanguage" lang="tr" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="dictionary.xsd">
<STRING id="AI.Directory.DefaultDefaultDir" value="Yeni Klasör"/>
<STRING id="AI.Directory.Default32BitName" value="Otuziki bit"/>
</DICTIONARY>
And below "general.xml" file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DICTIONARY type="singlelanguage" lang="neutral" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="dictionary.xsd">
<STRING id="AI.Directory.DefaultDefaultDir" value="New Folder"/>
<STRING id="AI.Directory.Default32BitName" value="32-bit"/>
<STRING id="AI.DuplicateFile.DestName" value="Duplicate%s of %s"/>
<STRING id="AI.Feature.DefaultTitle" value="Feature"/>
</DICTIONARY>
If I manage it, it will be like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DICTIONARY type="singlelanguage" lang="neutral" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="dictionary.xsd">
<STRING id="AI.Directory.DefaultDefaultDir" value="Yeni Klasör"/>
<STRING id="AI.Directory.Default32BitName" value="Otuziki bit"/>
<STRING id="AI.DuplicateFile.DestName" value="Duplicate%s of %s"/>
<STRING id="AI.Feature.DefaultTitle" value="Feature"/>
</DICTIONARY>
I do not know how I will manage it.
Kind regards.
You can try to load both files in to a DOMDocument, then loop through the general file. Inside the loop, you can see if there is a turkish value and just replace it. See http://www.php.net/manual/en/book.dom.php
I will just give it a try. I have not tested this code, but hopefully you will manage to fix it. Should be something like this.
EDIT I did not use the $result value in the loop, try now
<?php
$turkish = new DOMDocument();
$turkish->load('turkish.xml');
$general = new DOMDocument();
$general->load('general.xml');
$strings = $general->getElementsByTagName('STRING');
$turkstrings = $turkish->getElementsByTagName('STRING');
foreach($strings as $string) {
foreach($turkstrings as $turk) {
if($turk->getAttribute("id") == $string->getAttribute("id")) {
$string->setAttribute("value", $turk->getAttribute("value"));
}
}
}
echo $general->saveXML();
?>
I'm not sure if what you ask for is really useful because the software should already complete incomplete translation files with the defaults on the fly.
But sure technically it is possible, for example by going through the turkish XML and changing each corresponding entry in the general XML:
$new = simplexml_load_string($general);
$elements = simplexml_load_string($turkish)->STRING;
foreach ($elements as $element)
{
$xpath = sprintf('//STRING[#id="%s"]', $element['id']);
if (list($found) = $new->xpath($xpath))
{
$found['value'] = $element['value'];
$found['imported'] = 'turkish';
}
}
$new->asXML('php://output');
This example uses PHPs SimpleXML library. The output:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DICTIONARY xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" type="singlelanguage" lang="neutral" xsi:noNamespaceSchemaLocation="dictionary.xsd">
<STRING id="AI.Directory.DefaultDefaultDir" value="Yeni Klasör" imported="turkish"/>
<STRING id="AI.Directory.Default32BitName" value="Otuziki bit" imported="turkish"/>
<STRING id="AI.DuplicateFile.DestName" value="Duplicate%s of %s"/>
<STRING id="AI.Feature.DefaultTitle" value="Feature"/>
</DICTIONARY>
See it in action.

Categories