0

I am beginner in php and currently working on php-xml parsing in which i am not getting how should i append node with specific node having different value in same xml file.

Explanation : Since i don't have enough data so i need to duplicate nodes (here it is test node) so that i can increase my file size and then work on parsing.

In short i need to generate big xml file with exisitng single node.

Current Xml File :

         <?xml version="1.0" encoding="utf-8"?>
<Testings xmlns="http://rets.org/xsd/Syndication/2012-03" xmlns:Level="http://rets.org/xsd/RETSLevel" xmlns:schemaLocation="http://rets.org/xsd/Syndication/2012-03/Syndication.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="0.96" versionTimestamp="2012-02-07T03:00:00Z" xml:lang="en-us">
    <Test>
        <Area>
            <Level:preference-order>1</Level:preference-order>
            <Level:address-preference-order>1</Level:address-preference-order>
            <Level:FullStreetAddress>2245 Don Knotts Blvd.</Level:FullStreetAddress>
            <Level:UnitNumber>2</Level:UnitNumber>
            <Level:City>Morgantown</Level:City>
            <Level:StateOrProvince>WV</Level:StateOrProvince>
            <Level:PostalCode>26501</Level:PostalCode>
            <Level:Country>true</Level:Country>
        </Area>
        <AreaPrice Level:isgSecurityClass="Public">234000</ListPrice>
        <AreaPriceLow Level:isgSecurityClass="Public">214000</ListPriceLow>
        <AreaPrices>
            <AreaPrice>
                <AreaListPrice Level:currencyCode="AUS" Level:isgSecurityClass="Public">483999.0</AreaListPrice>
                <AreaListPriceLow Level:currencyCode="EUR" Level:isgSecurityClass="Public">470000.0</AreaListPriceLow>
            </AreaPrice>
        </AreaPrices>
    </Test>
</Testings>

Expected Output:

 <?xml version="1.0" encoding="utf-8"?>
<Testings xmlns="http://rets.org/xsd/Syndication/2012-03" xmlns:Level="http://rets.org/xsd/RETSLevel" xmlns:schemaLocation="http://rets.org/xsd/Syndication/2012-03/Syndication.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="0.96" versionTimestamp="2012-02-07T03:00:00Z" xml:lang="en-us">
        <Test>
            <Area>
                <Level:preference-order>1</Level:preference-order>
                <Level:address-preference-order>1</Level:address-preference-order>
                <Level:FullStreetAddress>2245 Don Knotts Blvd.</Level:FullStreetAddress>
                <Level:UnitNumber>2</Level:UnitNumber>
                <Level:City>Morgantown</Level:City>
                <Level:StateOrProvince>WV</Level:StateOrProvince>
                <Level:PostalCode>26501</Level:PostalCode>
                <Level:Country>true</Level:Country>
            </Area>
            <AreaPrice Level:isgSecurityClass="Public">234000</ListPrice>
            <AreaPriceLow Level:isgSecurityClass="Public">214000</ListPriceLow>
            <AreaPrices>
                <AreaPrice>
                    <AreaListPrice Level:currencyCode="AUS" Level:isgSecurityClass="Public">483999.0</AreaListPrice>
                    <AreaListPriceLow Level:currencyCode="EUR" Level:isgSecurityClass="Public">470000.0</AreaListPriceLow>
                </AreaPrice>
            </AreaPrices>
        </Test>

      <Test>
            <Area>
                <Level:preference-order>1</Level:preference-order>
                <Level:address-preference-order>1</Level:address-preference-order>
                <Level:FullStreetAddress>2245 Don Knotts Blvd.</Level:FullStreetAddress>
                <Level:UnitNumber>2</Level:UnitNumber>
                <Level:City>Morgantown</Level:City>
                <Level:StateOrProvince>WV</Level:StateOrProvince>
                <Level:PostalCode>26501</Level:PostalCode>
                <Level:Country>true</Level:Country>
            </Area>
            <AreaPrice Level:isgSecurityClass="Public">15000</ListPrice>
            <AreaPriceLow Level:isgSecurityClass="Public">214000</ListPriceLow>
            <AreaPrices>
                <AreaPrice>
                    <AreaListPrice Level:currencyCode="AUS" Level:isgSecurityClass="Public">483999.0</AreaListPrice>
                    <AreaListPriceLow Level:currencyCode="EUR" Level:isgSecurityClass="Public">470000.0</AreaListPriceLow>
                </AreaPrice>
            </AreaPrices>
        </Test>
</Testings>

**My Approach **

$xmlString = simplexml_load_string(file_get_contents('./PhpXmlFile.xml'));
$xmlString = $xmlString->xpath('/Testings/Test/');


if ( $xmlString && is_array( $xmlString ) ) {
    // since it IS an array, set to the first element of the array
    $xmlString = $xmlString[0];
    // And NOW we can append
    $xmlString = $xmlString->addChild('Test','');
}


$dom = new DOMDocument("1.0");
$dom->preserveWhiteSpace = true;
$dom->formatOutput = true;
$dom->loadXML($xmlString->saveXML());

Thanks in advance!!

Menick
  • 3
  • 4

1 Answers1

0

Here we are using DOMDocument for cloning a child node. Here for an example i am using nodeValue as 1000 you can change it to the value you want.

Here in a below code we are using $domDocument->getElementsByTagName("AreaPrice")->item(2)->nodeValue=1000; for item no 2 because after appending the a clone node, There will be four elements with name AreaPrice.

Try this code snippet here

<?php
ini_set('display_errors', 1);

$string = <<<HTML
<?xml version="1.0" encoding="utf-8"?>
<Testings xmlns="http://rets.org/xsd/Syndication/2012-03" xmlns:Level="http://rets.org/xsd/RETSLevel" xmlns:schemaLocation="http://rets.org/xsd/Syndication/2012-03/Syndication.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="0.96" versionTimestamp="2012-02-07T03:00:00Z" xml:lang="en-us">
    <Test>
        <Area>
            <Level:preference-order class='sas'>1</Level:preference-order>
            <Level:address-preference-order>1</Level:address-preference-order>
            <Level:FullStreetAddress>2245 Don Knotts Blvd.</Level:FullStreetAddress>
            <Level:UnitNumber>2</Level:UnitNumber>
            <Level:City>Morgantown</Level:City>
            <Level:StateOrProvince>WV</Level:StateOrProvince>
            <Level:PostalCode>26501</Level:PostalCode>
            <Level:Country>true</Level:Country>
        </Area>
        <AreaPrice Level:isgSecurityClass="Public">234000</AreaPrice>
        <AreaPriceLow Level:isgSecurityClass="Public">214000</AreaPriceLow>
        <AreaPrices>
            <AreaPrice>
                <AreaListPrice Level:currencyCode="AUS" Level:isgSecurityClass="Public">483999.0</AreaListPrice>
                <AreaListPriceLow Level:currencyCode="EUR" Level:isgSecurityClass="Public">470000.0</AreaListPriceLow>
            </AreaPrice>
        </AreaPrices>
    </Test>
</Testings>
HTML;

$domDocument = new DOMDocument();
$domDocument->loadXML($string);
$results=$domDocument->getElementsByTagName("Test");


$clonedNode=$results->item(0)->cloneNode(true);
$results->item(0)->parentNode->appendChild($clonedNode);


$domDocument->getElementsByTagName("AreaPrice")->item(2)->nodeValue=1000;//change the value you want.

echo $domDocument->saveXML();
Sahil Gulati
  • 15,028
  • 4
  • 24
  • 42
  • Thanks sahil !! Your solution bring me almost to my task . Any other query will surely ask to you :) +1 – Menick May 25 '17 at 07:22
  • There is one more question : As we use fread() in order to read certain bytes of data from file . But in this case i have to read specific number of nodes (like 10 Test node at a time) how we can do that ?? Any idea please help or just tell me logic because i have to do in Nodejs – Menick May 25 '17 at 07:38
  • Current XML is invalid: element type "AreaPrice" must be terminated by the matching end-tag "". – mike May 25 '17 at 08:19
  • @mike Sorry that was some mistake don't how anyways above solution has solved my problem . Thanks – Menick May 25 '17 at 08:29
  • Thanks @SahilGulati – Menick May 25 '17 at 09:16
  • @Menick I haven't used node.js :( , but from `PHP` you can do it like this first get the content of file, then do `XPath` query to return specific nodes you want. – Sahil Gulati May 25 '17 at 10:50
  • @SahilGulati I can't do like that way because i dont need to load entire file into memory i have to work on chunks which fread() in php provide :) – Menick May 25 '17 at 11:46