0

The below is my sample xml data

<?xml version="1.0"?>
<catalog>
      <book>
         <book NAME="ci_id">
            <PVAL><![CDATA[78965]]></PVAL>
         </book>
         <author>testing</author>
         <title>Md kaif khan</title>
         <genre>kkkk</genre>
         <price>5.95</price>
         <publish_date>2016-09-10</publish_date>
         <description>No...........</description>
      </book>
      <book>
         <book NAME="ci_id">
            <PVAL><![CDATA[78965]]></PVAL>
         </book>
         <author>asdfsaf</author>
         <title>Md asdfsaf khan</title>
         <genre>Age</genre>
         <price>6.95</price>
         <publish_date>2016-09-10</publish_date>
         <description>Asd</description>
      </book>
      <book>
         <book NAME="ci_id">
            <PVAL><![CDATA[5210]]></PVAL>
         </book>
         <author>Test</author>
         <title>Testing second</title>
         <genre>Ttt</genre>
         <price>8.94</price>
         <publish_date>2013-10-15</publish_date>
         <description>Nothing</description>
      </book>
   </catalog>

Here my requirement is to add multiple records i.e,from < book>... < /book> based on id(i.e, CDATA[78965]).

<?php
$xmlFileToLoad   =  dirname(__FILE__) .'/testing.xml';
      $xmlFileToSave   =  'testing-modified.xml';

      $cdata_text = '
      <book>
         <book NAME="ci_id">
            <PVAL><![CDATA[78965]]></PVAL>
         </book>
         <author>testing</author>
         <title>First</title>
         <genre>kk</genre>
         <price>5.95</price>
         <publish_date>2016-09-10</publish_date>
         <description>Just i am testing.</description>
      </book>
      <book>
         <book NAME="ci_id">
            <PVAL><![CDATA[78965]]></PVAL>
         </book>
         <author>testing1</author>
         <title>Second</title>
         <genre>kone</genre>
         <price>5.12</price>
         <publish_date>2014-10-20</publish_date>
         <description>i am testing One.</description>
      </book>
      ';

      $dom = new DOMDocument();
      $dom->load($xmlFileToLoad);
      $xpath = new DOMXPath($dom);

    function findStopPointByName($xml, $query) {
      $upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZAZSCZCÓL";
      $lower = "abcdefghijklmnopqrstuvwxyzazscznól";
      $arg_query    = "translate(text(), '$upper', '$lower')";
      $q = "//book[book/PVAL[contains($arg_query, '$query')]]" ."\n";
      return $xml->query($q);
    }

    foreach(findStopPointByName($xpath,'78965') as $node)
    {
      // Save parent - after removing node we will use it
      $parent = $node->parentNode;
      $parent->removeChild($node);

      // Load XML from text. You cann't append text, only node
      $data = new DOMDocument();
      $data->loadXML($cdata_text);

      // Import all new XML to our one and append to saved parent
      $ndata =  $dom->importNode($data->documentElement, true);   
      $parent->appendChild($ndata); 
    }

    $dom->save($xmlFileToSave);

Here in the above code in $cdata_text, when i use single record(< book>..< /book>) is it added correctly in the destination file. But i need to add there two record(which have same id(i.e,78965, actually in my code i am search with the specific id in the xml and updating with the $cdata_text with that, when i use single record it is updating, but now i want to add multiple records which the same id(from the $cdata_text) Or i can say, i need to find the id from the xml file and need to update it with the $cdata_text string.

Please guide me.

1 Answer 1

2

You current source loads a fragment string as a separate document. This will fail because an wellformed XML document can only have a single document element node.

A document fragment is a special node type in DOM, so you can create and append it like any other node. It has a method appendXml() to parse the XML fragment string.

Here is a simple example:

$document = new DOMDocument();
$document->loadXml('<catalog/>');

$fragment = $document->createDocumentFragment();
$fragment->appendXml(
  '<book><title>First</title></book>
   <book><title>Second</title></book>'
);

$document->documentElement->appendChild($fragment);

echo $document->saveXml();

Output:

<?xml version="1.0"?>
<catalog><book><title>First</title></book>
   <book><title>Second</title></book></catalog> 
Sign up to request clarification or add additional context in comments.

4 Comments

Hi @ThW, thanks for your help. updated my code foreach(findStopPointByName($xpath,'78965') as $node) { $parent = $node->parentNode; $parent->removeChild($node); $document = new DOMDocument(); $document->loadXml('<catalog/>'); $fragment = $document->createDocumentFragment(); $fragment->appendXml($cdata_text); $ndata = $document->documentElement->appendChild($fragment); $ndata1 = $dom->importNode($document->documentElement, true); $dom->appendChild($ndata1); } $dom->save($xmlFileToSave); in the above main code. output is not correct
Hi @ThW, the output contains more catalog nodes, Can you please help me
You should not load '<catalog/>' inside your function. The fragment replaces the creation and loading of the document inside your function. The first two lines are preparing a document so that the fragment has a target - making the example self contained and working: eval.in/627067
thanks for your reply, as i am new to xml, facing some issue, Can you please take a look on these code. eval.in/627261 once again thanks for your great support

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.