I have a problem composing XML sitemap using simple xml PHP function, having almost equal situation and when sitemap tag, it is not working:
$xml = simplexml_load_string('<?xml version="1.0" encoding="UTF-8"?><sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></urlset>');
$sitemap = $xml->addChild("sitemap");
$sitemap->addChild("loc", "http://www.example.com/sitemap-1.xml");
Fatal error: Call to a member function addChild() on boolean
This is working reliably:
$xml = simplexml_load_string('<?xml version="1.0" encoding="utf-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></urlset>');
$url = $xml->addChild("url");
$url->addChild("loc", "http://www.example.com/sitemap-2.xml");
Your issue is caused by simple mistake.
(you have - maybe forgot to change - closing tag from urlset to sitemapindex):
$xml = simplexml_load_string('<?xml version="1.0" encoding="UTF-8"?><sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></urlset>');
Correct:
$xml = simplexml_load_string('<?xml version="1.0" encoding="UTF-8"?><sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></sitemapindex>');
Related
I'm generating some XML data in response to an HTTP POST request. I'm setting the MIME
header('Content-type: text/xml');
and everything is working well so far.
I'm generating the xml response as follows:
$response = '<?xml version="1.0" encoding="utf-8"?>';
$response .= '<error>';
$response .= '<description>'.$error.'</description>';
$response .= '</error>';
echo $response;
I would now like the format the XML so that instead of seeing this response:
<?xml version="1.0" encoding="utf-8"?><error><description>Login Error: No Username Supplied</description></error>
they see this response:
<?xml version="1.0" encoding="utf-8"?>
<error>
<description>Login Error: No Username Supplied</description>
</error>
I haven't worked with XML output with PHP before so not sure if there's a built in method for doing a "pretty print" type function on the output?
Use the DOM library and set the formatOutput property to true
$doc = new DOMDocument('1.0', 'utf-8');
$doc->formatOutput = true;
$root = $doc->createElement('error');
$doc->appendChild($root);
$desc = $doc->createElement('description', $error);
$root->appendChild($desc);
echo $doc->saveXML();
Demo ~ https://eval.in/461384
I have the following code
$base = '<?xml version="1.0" encoding="UTF-8"?><realestates:office xmlns:realestates="http://rest.immobilienscout24.de/schema/offer/realestates/1.0" xmlns:xlink="http://www.w3.org/1999/xlink"></realestates:office>';
$objXml = new \SimpleXMLElement($base);
$objXml->addChild('title', 'Alles Toller');
$strXml = $objXml->asXML();
$strXml would now be
<?xml version="1.0" encoding="UTF-8"?>
<realestates:office xmlns:realestates="http://rest.immobilienscout24.de/schema/offer/realestates/1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
<realestates:title>Alles Toller</realestates:title>
</realestates:office>
What I want is to not have the realestates: prefix in <title>
<?xml version="1.0" encoding="UTF-8"?>
<realestates:office xmlns:realestates="http://rest.immobilienscout24.de/schema/offer/realestates/1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Alles Toller</title>
</realestates:office>
How can I accomplish that?
I ended up in using DOMDocument:
$objXml = new \DOMDocument( "1.0", "UTF-8" );
$objRoot = $objXml->createElement('realestates:office');
$objXml->appendChild($objRoot);
$objXml->createAttributeNS('http://rest.immobilienscout24.de/schema/offer/realestates/1.0', 'realestates:office');
$objXml->createAttributeNS('http://www.w3.org/1999/xlink', 'xlink:dummy');
$objTitle = $objXml->createElement('title', 'Alles Toll');
$objRoot->appendChild($objTitle);
$strXml = $objXml->saveXML();
The second parameter of createAttributeNS() is a bit strange - only the namespace is not enough, it looks like I have to also add an element name.
The xml is as follows:
<root>
<organizations>
<organization>
<info>
<orgID>1234</orgID>
<orgName>XYZ Company</orgName>
<address>
<address1>1 Main Street</address1>
<city>Somewhere</city>
<state>MI</state>
<zip>12334</zip>
</address>
</info>
</organization>
</organizations>
</root>
The code is as follows:
$ind = strpos($xmlResponse, "<");
$xml = simplexml_load_string(substr($xmlResponse, $ind));
//echo $xml;
$orgList = $xml->organizations->children();
foreach($orgList as $orgList)
{
echo $orgList->orgName;
}
And I get the following error:
Warning: main() [function.main]: Node no longer exists in...
The offending line is
foreach($orgList as $orgList)
Can anyone tell me what I'm doing wrong? I've tried accessing the xml through 50 different ways and either get that error or an empty xml object.
Thanks in advance!
It looks like you're overwriting the xml object when you loop with $orgList as $orgList. Try this instead:
foreach($orgList as $org)
echo $org->orgName;
Try the following:
$xml = simplexml_load_string($xml);
$org = $xml->organizations->children();
foreach($org as $k => $v)
{
echo $v->info->orgName;
}
Try using xpath
Put the XML in x.xml file
then create php file:
<?php
$xml = simplexml_load_file('x.xml');
$orgList = $xml->xpath("/root/organizations/organization/info");
print $orgList[0]->orgName;
?>
I have an XML document and want to insert a new node at a specific spot using SimpleXML.
The original XML is this:
<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>
<create>
<domain:create
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0"
xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd"
>
<domain:period unit="y"></domain:period>
</domain:create>
</create>
</command>
</epp>
after <domain:create> I need to add the following node:
<domain:ns>
<domain:hostAttr>
<domain:hostName></domain:hostName>
<domain:hostAddr ip="v4"></domain:hostAddr>
</domain:hostAttr>
</domain:ns>
How can I do that? I have tried this:
$xmlObj = simplexml_load_file('myXMLFile.xml');
$nsNode = $xmlObj->command->create->children(self::OBJ_URI_DOMAIN)->create->addChild('domain:ns');
$hostAttr = $nsNode->addChild('domain:hostAttr');
$hostName = $hostAttr->addChild('domain:hostName');
$hostAddr = $hostAttr->addChild('domain:hostAddr');
$hostAddr->addAtribute('ip', 'v4');
On this first line, I'm getting this warning:
Warning: SimpleXMLElement::addChild()
[simplexmlelement.addchild]: Cannot
add child. Parent is not a permanent
member of the XML tree
On the second line, and because of this, I'm getting:
Fatal error: Call to a member function
addChild() on a non-object
Thanks in advance.
Additional notes:
- The php version is higher then 5.1;
- I have successfully added child nodes later on this same XML.
I cannot reproduce the first error
<?php
echo phpversion(), "\n";
// $xmlObj = simplexml_load_file('myXMLFile.xml');
$xmlObj = getDoc();
$nsNode = $xmlObj->command->create->children('urn:ietf:params:xml:ns:domain-1.0')->create->addChild('domain:ns');
$nsNode->addChild('foo', 'Mary had a little lamb...');
echo $xmlObj->asxml();
function getDoc() {
return new SimpleXMLElement('<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>
<create>
<domain:create
xmlns:domain="urn:ietf:params:xml:ns:domain-1.0"
xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd"
>
<domain:period unit="y"></domain:period>
</domain:create>
</create>
</command>
</epp>');
}
prints
5.3.2
<?xml version="1.0"?>
<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>
<create>
<domain:create xmlns:domain="urn:ietf:params:xml:ns:domain-1.0" xsi:schemaLocation="urn:ietf:params:xml:ns:domain-1.0 domain-1.0.xsd">
<domain:period unit="y"/>
<domain:ns><domain:foo>Mary had a little lamb...</domain:foo></domain:ns></domain:create>
</create>
</command>
</epp>
You want the child added to <create>.
$nsNode = $xmlObj->command->create->addChild('domain:ns');
The children() method returns a filtered list of child nodes. This list is - just as the error message indicates - not a permanent member of the document tree, it cannot be added to.
Adding a child works on the respective parent element only, or the operation would not be called "addChild", but "addSibling" - and this is not how the concept of the DOM works.
PS: Your second error message ("Call to a member function on a non-object") is the result of regular sloppiness. You can't just use an object without checking that it is actually there, your code lacks this check:
if ($nsNode !== null) {
$hostAttr = $nsNode->addChild('domain:hostAttr');
$hostName = $hostAttr->addChild('domain:hostName');
$hostAddr = $hostAttr->addChild('domain:hostAddr');
$hostAddr->addAttribute('ip', 'v4');
} else {
echo "Oops, addChild() failed!";
}
<?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>