i have problem with simpleXml and adding new items. This is my xml:
<?xml version="1.0" encoding="utf-8"?>
<root>
<items>
<item>abc</item>
<item>def</item>
<item>ghi</item>
</items>
</root>
Im using this php code:
$xml = simplexml_load_file("myxml.xml");
$sxe = new SimpleXMLElement($xml->asXML());
$newItem = $sxe->addChild("items");
$newItem->addChild("item", $newValue);
$sxe->asXML("myxml.xml");
This is the result:
<?xml version="1.0" encoding="utf-8"?>
<root>
<items>
<item>abc</item>
<item>def</item>
<item>ghi</item>
</items>
<items>
<item>jkl</item>
</items>
</root>
This creates me new items node, but i want add item to the same already existing items node.
then, you should not create new items node:
$xml = simplexml_load_file("myxml.xml");
$sxe = new SimpleXMLElement($xml->asXML());
$itemsNode = $sxe->items[0];
$itemsNode->addChild("item", $newValue);
$sxe->asXML("myxml.xml");
Have you tried doing the following way
$newItem->root->items[0]->addChild("item","Test");
Or
$newItem->root->items->addChild("item","Test");
You can use this class to SimpleXML objects that accept children append
<?php
class MySimpleXMLElement extends SimpleXMLElement
{
/**
* Add SimpleXMLElement code into a SimpleXMLElement
*
* #param MySimpleXMLElement $append
*/
public function appendXML($append)
{
if ($append) {
if (strlen(trim((string)$append)) == 0) {
$xml = $this->addChild($append->getName());
} else {
$xml = $this->addChild($append->getName(), (string)$append);
}
foreach ($append->children() as $child) {
$xml->appendXML($child);
}
foreach ($append->attributes() as $n => $v) {
$xml->addAttribute($n, $v);
}
}
}
}
Related
I have an XML from Google with a content like this:
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">
<channel>
<title>E-commerce's products.</title>
<description><![CDATA[Clothing and accessories.]]></description>
<link>https://www.ourwebsite.com/</link>
<item>
<title><![CDATA[Product #1 title]]></title>
<g:brand><![CDATA[Product #1 brand]]></g:brand>
<g:mpn><![CDATA[5643785645]]></g:mpn>
<g:gender>Male</g:gender>
<g:age_group>Adult</g:age_group>
<g:size>Unica</g:size>
<g:condition>new</g:condition>
<g:id>fr_30763_06352</g:id>
<g:item_group_id>fr_30763</g:item_group_id>
<link><![CDATA[https://www.ourwebsite.com/product_1_url.htm?mid=62367]]></link>
<description><![CDATA[Product #1 description]]></description>
<g:image_link><![CDATA[https://data.ourwebsite.com/imgprodotto/product-1_big.jpg]]></g:image_link>
<g:sale_price>29.25 EUR</g:sale_price>
<g:price>65.00 EUR</g:price>
<g:shipping_weight>0.5 kg</g:shipping_weight>
<g:featured_product>y</g:featured_product>
<g:product_type><![CDATA[Product #1 category]]></g:product_type>
<g:availability>in stock</g:availability>
<g:availability_date>2022-08-10T00:00-0000</g:availability_date>
<qty>3</qty>
<g:payment_accepted>Visa</g:payment_accepted>
<g:payment_accepted>MasterCard</g:payment_accepted>
<g:payment_accepted>CartaSi</g:payment_accepted>
<g:payment_accepted>Aura</g:payment_accepted>
<g:payment_accepted>PayPal</g:payment_accepted>
</item>
<item>
<title><![CDATA[Product #2 title]]></title>
<g:brand><![CDATA[Product #2 brand]]></g:brand>
<g:mpn><![CDATA[573489547859]]></g:mpn>
<g:gender>Unisex</g:gender>
<g:age_group>Adult</g:age_group>
<g:size>Unica</g:size>
<g:condition>new</g:condition>
<g:id>fr_47362_382936</g:id>
<g:item_group_id>fr_47362</g:item_group_id>
<link><![CDATA[https://www.ourwebsite.com/product_2_url.htm?mid=168192]]></link>
<description><![CDATA[Product #2 description]]></description>
<g:image_link><![CDATA[https://data.ourwebsite.com/imgprodotto/product-2_big.jpg]]></g:image_link>
<g:sale_price>143.91 EUR</g:sale_price>
<g:price>159.90 EUR</g:price>
<g:shipping_weight>8.0 kg</g:shipping_weight>
<g:product_type><![CDATA[Product #2 category]]></g:product_type>
<g:availability>in stock</g:availability>
<g:availability_date>2022-08-10T00:00-0000</g:availability_date>
<qty>1</qty>
<g:payment_accepted>Visa</g:payment_accepted>
<g:payment_accepted>MasterCard</g:payment_accepted>
<g:payment_accepted>CartaSi</g:payment_accepted>
<g:payment_accepted>Aura</g:payment_accepted>
<g:payment_accepted>PayPal</g:payment_accepted>
</item>
...
</channel>
</rss>
I need to produce a XML file purged from all the tags inside <item> except for <g:mpn>, <link>, <g:sale_price> and <qty>.
In the example above, the result should be
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0">
<channel>
<title>E-commerce's products.</title>
<description><![CDATA[Clothing and accessories.]]></description>
<link>https://www.ourwebsite.com/</link>
<item>
<g:mpn><![CDATA[5643785645]]></g:mpn>
<link><![CDATA[https://www.ourwebsite.com/product_1_url.htm?mid=62367]]></link>
<g:sale_price>29.25 EUR</g:sale_price>
<qty>3</qty>
</item>
<item>
<g:mpn><![CDATA[573489547859]]></g:mpn>
<link><![CDATA[https://www.ourwebsite.com/product_2_url.htm?mid=168192]]></link>
<g:sale_price>143.91 EUR</g:sale_price>
<qty>1</qty>
</item>
...
</channel>
</rss>
I've looked at SimpleXML, DOMDocument, XPath docs but I couldn't find the way to exclude specific elements. I don't want to select by name the nodes I have to delete, as in a future Google could add some nodes and they will not be deleted by my script.
I've also tried to loop through namespaced elements with SimpleXML and unset them if not matched with the nodes I have to keep:
$g = $element->children($namespaces['g']); //$element is the SimpleXMLElement of <item> tag
foreach ($g as $gchild) {
if ($gchild->getName() != "mpn") { //for example
unset($gchild);
}
}
but the code above doesn't remove all nodes except for <g:mpn>, for example.
PS: consider the fact that the XML contains both namespaced and not namespaced elements
Thank you in advance.
EDIT:
I've managed to do this with the following code:
$elementsToKeep = array("mpn", "link", "sale_price", "qty");
$domdoc = new DOMDocument();
$domdoc->preserveWhiteSpace = FALSE;
$domdoc->formatOutput = TRUE;
$domdoc->loadXML($myXMLDocument->asXML()); //$myXMLDocument is the SimpleXML document related to the original XML
$xpath = new DOMXPath($domdoc);
foreach ($element->children() as $child) {
$cname = $child->getName();
if (!in_array($cname, $elementsToKeep)) {
foreach($xpath->query('/rss/channel/item/'.$cname) as $node) {
$node->parentNode->removeChild($node);
}
}
}
$g = $element->children($namespaces['g']);
foreach ($g as $gchild) {
$gname = $gchild->getName();
if (!in_array($gname, $elementsToKeep)) {
foreach($xpath->query('/rss/channel/item/g:'.$gname) as $node) {
$node->parentNode->removeChild($node);
}
}
}
I've used DOMDocument and DOMXPath and two loops on no-namespaced tags and namespaced tags, in order to use the removeChild function of DOMDocument.
Really there is not a cleaner solution?? Thanks again
Somewhat simpler:
$items = $xpath->query('//item');
foreach($items as $item) {
$targets = $xpath->query('.//*',$item);
foreach($targets as $target) {
if (!in_array($target->localName, $elementsToKeep)) {
$target->parentNode->removeChild($target);
}
};
};
Use XPath to express all child elements you want to remove.
Then use the library of your choice to remove the elements.
SimpleXMLElement example:
$sxe = simplexml_load_string($xml);
foreach ($sxe->xpath('//item/*[
not(
name() = "g:mpn"
or name() = "link"
or name() = "g:sale_price"
or name() = "qty"
)
]') as $child) unset($child[0]);
echo $sxe->asXML(), "\n";
DOMDocument example:
This one is mainly identical to the previous example, with a bit of a variation on the xpath expression to explicitly use namespace URIs for the elements. This prevents that it breaks when the namespace prefix changes (it also works in the SimpleXMLElement example):
$doc = new DOMDocument();
$doc->loadXML($xml);
$xpath = new DOMXPath($doc);
foreach ($xpath->query('//item/*[
not(
(local-name() = "mpn" and namespace-uri() = "http://base.google.com/ns/1.0")
or (local-name() = "link" and namespace-uri() = "")
or (local-name() = "sale_price" and namespace-uri() = "http://base.google.com/ns/1.0")
or (local-name() = "qty" and namespace-uri() = "")
)
]') as $child) {
$child->parentNode->removeChild($child);
}
echo $doc->saveXML(), "\n";
I have an XML file in which one child has two categories, but with the same name. I want to add one title to each one. How can we do it in PHP?
This is my XML
<root>
<result>
<node>
<title> Some Title Name</title>
<categories>
<category> categor_one </category>
<category> categor_two </category>
</categories>
</node>
<node>
<title> Some Title Name</title>
<categories>
<category> categor_one </category>
<category> categor_tree </category>
</categories>
</node>
</result>
</root>
But I want to obtain this
<root>
<result>
<node>
<title> Some Title Name</title>
<category>categor_one///categor_two </category>
<category1>categor_one///categor_tree</category1>
</node>
</result>
</root>
I managed to impement a function that only gets correctly the category, but if the title is the same it doesn't work as it just creates a new one.
function solve_something($xml, $destination)
{
$xml = simplexml_load_file($xml, "SimpleXMLElement", LIBXML_NOCDATA);
$json = json_encode($xml);
$items = json_decode($json, TRUE);
$products = array();
$product_data = array();
foreach($items['result']['node'] as $item){
$product_data['title'] = $item['title'];
foreach ($item['categories'] as $category) {
if (is_array($category)) {
$product_data['category'] = implode('///', $category);
} else {
$product_data['category'] = $category;
}
}
$products[] = $product_data;
unset($product_data);
}
$path = createXML($products, $destination);
return $path;
}
function createXML($data, $destination)
{
$xmlDoc = new DOMDocument('1.0', 'UTF-8');
$root = $xmlDoc->appendChild($xmlDoc->createElement("root"));
foreach ($data as $key => $product) {
$productA = $root->appendChild($xmlDoc->createElement('product'));
foreach ($product as $key1 => $val) {
if (!empty($val)) {
if ($key1 == 'price' || $key1 == 'tax' || $key1 == 'stockAmount') {
$productA->appendChild($xmlDoc->createElement($key1, $val));
} else {
$ProductKey = $productA->appendChild($xmlDoc->createElement($key1));
$ProductKey->appendChild($xmlDoc->createCDATASection($val));
}
}
}
}
$xmlDoc->formatOutput = true;
fn_rm($destination);
$xmlDoc->save($destination);
return $destination;
}
The output of my code is something like this
<root>
<product>
<title> Some Title Name</title>
<category>categor_one///categor_two </category>
</product>
<product>
<title> Some Title Name</title>
<category>categor_one///categor_tree</category>
</product>
</root>
If you want to keep the data together with the same title, one approach could be to collect that data upfront by using the title as an array key (if it is a valid array key)
When you create the xml, you have the title in the outer foreach loop as the key, and in the inner foreach you can create elements using implode.
Note that in your code you started using product so I took that as a node name.
Example code, which you could use in your code:
$products = array();
$product_data = array();
$xml = simplexml_load_file($xml, "SimpleXMLElement", LIBXML_NOCDATA);
foreach ($xml->result->node as $node) {
$product_data['title'] = (string)$node->title;
foreach($node->categories as $category) {
if (is_array($category)) {
$product_data['category'] = implode('///', $category);
continue;
}
$product_data['category'] = (array)$category->category;
}
$products[(string)$node->title][] = $product_data;
}
$xmlDoc = new DOMDocument('1.0', 'UTF-8');
$root = $xmlDoc->appendChild($xmlDoc->createElement("root"));
foreach ($products as $key => $product) {
$productA = $root->appendChild($xmlDoc->createElement('product'));
$productA->appendChild($xmlDoc->createElement("title", $key));
for ($i = 0; $i < count($product); $i++) {
$productA->appendChild($xmlDoc->createElement("category" . $i, implode("///", $product[$i]["category"])));
}
}
$xmlDoc->formatOutput = true;
echo $xmlDoc->saveXML();
Output
<?xml version="1.0" encoding="UTF-8"?>
<root>
<product>
<title> Some Title Name</title>
<category0> categor_one /// categor_two </category0>
<category1> categor_one /// categor_tree </category1>
</product>
</root>
Php demo
I have to create an xml out of other xml. I already have the answer to that, but then I'm facing another problem. The output of the xml is quite messy in the tag.
The xml is this:
<rss>
<item id="12907">
<g:productname>Black Bag</g:productname>
<g:detailed_images>
<g:detailed_image>Image1.jpg</g:detailed_image>
<g:detailed_image>Image2.jpg</g:detailed_image>
<g:detailed_image>Image3.jpg</g:detailed_image>
<g:detailed_image>Image4.jpg</g:detailed_image>
<g:detailed_image>Image5.jpg</g:detailed_image>
<g:detailed_image>Image6.jpg</g:detailed_image>
<g:detailed_image>Image7.jpg</g:detailed_image>
<g:detailed_image>Image8.jpg</g:detailed_image>
<g:detailed_image>Image9.jpg</g:detailed_image>
<g:detailed_image>Image10.jpg</g:detailed_image>
<g:detailed_image>Image11.jpg</g:detailed_image>
<g:detailed_image>Image12.jpg</g:detailed_image>
</g:detailed_images>
</item>
<item id="12906">
<g:productname>Yellow Bag</g:productname>
<g:detailed_images>
<g:detailed_image>Image1.jpg</g:detailed_image>
<g:detailed_image>Image2.jpg</g:detailed_image>
<g:detailed_image>Image3.jpg</g:detailed_image>
<g:detailed_image>Image4.jpg</g:detailed_image>
<g:detailed_image>Image5.jpg</g:detailed_image>
<g:detailed_image>Image6.jpg</g:detailed_image>
<g:detailed_image>Image7.jpg</g:detailed_image>
<g:detailed_image>Image8.jpg</g:detailed_image>
<g:detailed_image>Image9.jpg</g:detailed_image>
<g:detailed_image>Image10.jpg</g:detailed_image>
<g:detailed_image>Image11.jpg</g:detailed_image>
<g:detailed_image>Image12.jpg</g:detailed_image>
</g:detailed_images>
</item>
</rss>
The php code that I'm using to create another xml file is this
<?php
$document = new DOMDocument;
$document->formatOutput = true;
$document->preserveWhiteSpace = false;
$document->load('xml_feeds.xml');
$xpath = new DOMXPath($document);
$fields = [
'productname' => 'string(g:productname)',
'detailed_images' => 'string(g:detailed_images)'
];
$xml = new DOMDocument;
$xml->formatOutput = true;
$xml->preserveWhiteSpace = false;
$rss = $xml->appendChild($xml->createElement('rss'));
foreach ($xpath->evaluate('//item') as $item) {
//create tag item
$createItem = $rss->appendChild($xml->createElement('item'));
//getting item's attribute value
$valueID = $item->getAttribute('id');
//create attribute
$itemAttribute = $xml->createAttribute('id');
$itemAttribute->value = $valueID;
$createItem->appendChild($itemAttribute);
foreach ($fields as $caption => $expression) {
$value = $xpath->evaluate($expression, $item);
$createItem->appendChild($xml->createElement($caption, $value));
}
}
$xml->save('new_createxml2.xml');
?>
The result of the new_createxml2.xml is this
<?xml version="1.0"?>
<rss>
<item id="12907">
<productname>Black Bag</productname>
<detailed_images>Image1.jpgImage2.jpgImage3.jpgImage4.jpgImage3.jpgImage4.jpgImage5.jpgImage6.jpgImage7.jpgImage8.jpgImage9.jpgImage10.jpgImage11.jpgImage12.jpg</detailed_images>
</item>
<item id="12906">
<productname>Yellow Bag</productname>
<detailed_images>Image1.jpgImage2.jpgImage3.jpgImage4.jpgImage3.jpgImage4.jpgImage5.jpgImage6.jpgImage7.jpgImage8.jpgImage9.jpgImage10.jpgImage11.jpgImage12.jpg</detailed_images>
</item>
</rss>
I really wonder how can I create the xml tidier than what I've made. I want it to display like this actually:
<?xml version="1.0"?>
<rss>
<item id="12907">
<productname>Black Bag</productname>
<detailed_images>Image1.jpg, Image2.jpg, Image3.jpg, Image4.jpg, Image3.jpg, Image4.jpg, Image5.jpg, Image6.jpg, Image7.jpg, Image8.jpg, Image9.jpg, Image10.jpg, Image11.jpg, Image12.jpg</detailed_images>
</item>
<item id="12906">
<productname>Yellow Bag</productname>
<detailed_images>Image1.jpg, Image2.jpg, Image3.jpg, Image4.jpg, Image3.jpg, Image4.jpg, Image5.jpg, Image6.jpg, Image7.jpg, Image8.jpg, Image9.jpg, Image10.jpg, Image11.jpg, Image12.jpg</detailed_images>
</item>
</rss>
Thank you for your help
The way you've tried it is quite simple for some things, but as you've found out that this method fails when you want processing for each individual piece of data. When you use 'string(g:detailed_images)' - this is the text content of all of the subnodes in your document, which is why you have all of the values stuck together. You could then process this string with some form of regular expression - but as you have no control of the content it's difficult to know what you are going to find.
Changing it to a more traditional - get values using a specific XPath call and processing the values allows you more control over the result.
foreach ($xpath->evaluate('//item') as $item) {
//create tag item
$createItem = $rss->appendChild($xml->createElement('item'));
//getting item's attribute value
$valueID = $item->getAttribute('id');
//create attribute
$itemAttribute = $xml->createAttribute('id');
$itemAttribute->value = $valueID;
$createItem->appendChild($itemAttribute);
$prodName = $xpath->evaluate("string(g:productname)", $item);
$createItem->appendChild($xml->createElement('productname', $prodName));
$images = [];
foreach ( $xpath->query("descendant::g:detailed_image", $item) as $image ) {
$images[] = $image->nodeValue;
}
$createItem->appendChild($xml->createElement('detailed_images',
implode(",", $images)));
}
I want to read the following xml and find specific xml tags by their id values , Finally i want to copy these selected tags inside another xml using php user define class methods: sample given below:
<items>
<item>
<id>1</id>
<name>Item-1</name>
<price>10</price>
</item>
<item>
<id>2</id>
<name>Item-2</name>
<price>20</price>
</item>
<item>
<id>3</id>
<name>Item-3</name>
<price>30</price>
</item>
</items>
<customer>
<purchasedItems>
// add the xml here for the purchased Item chosen by id values
</purchasedItems>
</customer>
If customer purchased Item-1 and Item-3, then output will be:
<customer>
<purchasedItems>
<item>
<id>1</id>
<name>Item-1</name>
<price>10</price>
</item>
<item>
<id>3</id>
<name>Item-3</name>
<price>30</price>
</item>
</purchasedItems>
</customer>
i try with the following code which is not working :
<?php
header('Content-Type: text/xml');
class Items {
public static function addItem($purchasedItemsXml, $Items, $parentTag, $idTag ,$id)
{
$docSource = new DOMDocument();
$docSource->loadXML($Items);
$docDest = new DOMDocument();
$docDest->loadXML($purchasedItemsXml);
$xpath = new DOMXPath($docSource);
$result = $xpath->query("//{$idTag}[text()='{$id}']/parent::*");
$result = $docDest->importNode($result->item(0), true);
$items = $docDest->getElementsByTagName($parentTag)->item(0);
$items->appendChild($result);
echo $docDest->saveXML();
return ;
}
}
Updates: After changing Following code,Now Its Working Thanks to all.
class purchasedItems extends Items{
public static function addPurchasedItems($purchasedItemsXml, $Items, $parentTag, $idTag, $ids){
$count =0;
foreach ($ids as $id) {
if($count==0){
$xml = self::addItem($purchasedItemsXml, $Items, $parentTag, $idTag, $id);
}
else{
$xml = self::addItem($xml, $Items, $parentTag, $idTag, $id);
}
$count++;
}
echo $xml;
return ;
}
}
$Items = "<items>
<item>
<id>1</id>
<name>Item-1</name>
<price>10</price>
</item>
<item>
<id>2</id>
<name>Item-2</name>
<price>20</price>
</item>
<item>
<id>3</id>
<name>Item-3</name>
<price>30</price>
</item>
</items>";
$purchasedItemsXml = "<customer>
<purchasedItems>
</purchasedItems>
</customer>";
$ids = array(1, 3);
$parentTag = 'purchasedItems';
$idTag = 'id';
purchasedItems::addPurchasedItems($purchasedItemsXml, $Items, $parentTag, $idTag, $ids);
?>
as a beginner, i am sure i did some mistake, but i am now stuck at point.I want to do this using the existing given class hierarchy.please help me with this code.Thanks
You can achive this by using SimpleXML:
$xml = new SimpleXMLElement($purchasedItemsXml);
Then access like this: echo $xml->purchasedItems->item[0]->name;
To access children elements of a tag do this:
foreach($xml->purchasedItems->item as $item)
{
echo $item->name; //and other properties like this.
//if not sure try var_dump($item) here it will tell you.
}
Common mistake is to reference root element in your code, don't do that, or it won't work, you need to omit root element, in your case customer.
EDIT: To add items, find the items like I showed above, and add them like this:
$item = $xml->purchasedItems->addChild('item');
$item->addChild('name', 'SimpleXML Rocks just like that');
$item->addChild('id', '3');
echo $xml->saveXML();
Your “core” code is fine, but the classes construction is wrong (parent::addItem doesn't exist and addPayHead echoes one document for each added item).
This code — without classes — will work:
$ids = array(1, 3);
$parentTag = 'purchasedItems';
$idTag = 'id';
$docSource = new DOMDocument();
$docSource->loadXML($Items);
$docDest = new DOMDocument();
$docDest->loadXML($purchasedItemsXml);
$xpath = new DOMXPath($docSource);
foreach( $ids as $id )
{
$query = "//{$idTag}[text()='{$id}']/parent::*";
$result = $xpath->query( $query );
$result = $docDest->importNode($result->item(0), true);
$items = $docDest->getElementsByTagName($parentTag)->item(0);
$items->appendChild($result);
}
echo $docDest->saveXML();
I am having the XML like this
<?xml version="1.0" encoding="utf-8"?>
<root>
<mynode catid="10" catname="Animals" label="Animals" catdesc="" parent_id="2">
<mynode catid="11" catname="Lions" label="Lions" catdesc="" parent_id="10">
<mynode catid="12" catname="lion" label="lion" catdesc="" parent_id="11"/>
<mynode catid="13" catname="lioness" label="lioness" catdesc="" parent_id="11"/>
</mynode>
</mynode>
</root>
From this I want to remove
<?xml version="1.0" encoding="utf-8"?>
<root>
and
</root>
So expected result is
<mynode catid="10" catname="Animals" label="Animals" catdesc="" parent_id="2">
<mynode catid="11" catname="Lions" label="Lions" catdesc="" parent_id="10">
<mynode catid="12" catname="lion" label="lion" catdesc="" parent_id="11"/>
<mynode catid="13" catname="lioness" label="lioness" catdesc="" parent_id="11"/>
</mynode>
</mynode>
How can I do this?
Edit 1:TO Phil
$dom = new DomDocument();
//$dom->preserveWhitespace = false;
$dom->load('treewithchild.xml');
function DOMinnerHTML($element)
{
$innerHTML = "";
$children = $element->childNodes;
foreach ($children as $child)
{
$tmp_dom = new DOMDocument();
$tmp_dom->appendChild($tmp_dom->importNode($child, true));
$innerHTML.=trim($tmp_dom->saveXML());
echo $tmp_dom->saveXML();
}
return $innerHTML;
}
$dom->preserveWhiteSpace = false;
$domTable = $dom->getElementsByTagName("mynode");
foreach ($domTable as $tables)
{
//echo $tables;
DOMinnerHTML($tables);
}
As you want the inner markup of the <root> node, that is the element who's child nodes you'll want to iterate. You can access this element using the DOMDocument::documentElement property.
Try this (tested and working)
$doc = new DOMDocument;
$doc->load('treewithchild.xml');
$inner = '';
foreach ($doc->documentElement->childNodes as $child) {
$inner .= $doc->saveXML($child);
}
echo $inner;
I expect that the root element is returned also, you have to know that for each xml file an is added impliicitly, even if it exists in your file. so try to do this
$children = $element->childNodes->childNodes;
i think that would help you.