0

I have a xml of multilevel nodes. I can find the node but need to know how to update the node values. In my file bellow, I can find the node channels by its attribute but how can I update values of node like channelType or others?

Here is my XML file with code What I've done.

<?xml version="1.0"?>
<systemConfigs>
<systemConfig cnfId="1">
    <moduleName>Module 1</moduleName>
    <channeles ch="1">
        <chId>1</chId>
        <channelName>Channel 1 of Module 1</channelName>
        <channelType>myFunc 1</channelType>
        <channelFunc>conFig</channelFunc>
        <eu>myFunc 1</eu>
        <custScale>myFunc 1</custScale>
        <rawMin>myFunc 1</rawMin>
        <rawMax>myFunc 1</rawMax>
        <euMin>myFunc 1</euMin>
        <euMax>myFunc 1</euMax>
        <dspFormat>myFunc 1</dspFormat>
        <digOfPrec>myFunc 1</digOfPrec>
    </channeles>
    <channeles ch="2">
        <chId>2</chId>
        <channelName>Channel 2 of Module 1</channelName>
        <channelType>myFunc 2</channelType>
        <channelFunc>conFig</channelFunc>
        <eu>myFunc 2</eu>
        <custScale>myFunc 2</custScale>
        <rawMin>myFunc 2</rawMin>
        <rawMax>myFunc 2</rawMax>
        <euMin>myFunc 2</euMin>
        <euMax>myFunc 2</euMax>
        <dspFormat>myFunc 2</dspFormat>
        <digOfPrec>myFunc 2</digOfPrec>
    </channeles>
</systemConfig>
<systemConfig cnfId="2">
    <moduleName>Module 2</moduleName>
    <channeles ch="3">
        <chId>3</chId>
        <channelName>Channel 1 of Module 2</channelName>
        <channelType>myFunc 1</channelType>
        <channelFunc>conFig</channelFunc>
        <eu>myFunc 1</eu>
        <custScale>myFunc 1</custScale>
        <rawMin>myFunc 1</rawMin>
        <rawMax>myFunc 1</rawMax>
        <euMin>myFunc 1</euMin>
        <euMax>myFunc 1</euMax>
        <dspFormat>myFunc 1</dspFormat>
        <digOfPrec>myFunc 1</digOfPrec>
    </channeles>
    <channeles ch="4">
        <chId>4</chId>
        <channelName>Channel 2 of Module 2</channelName>
        <channelType>myFunc 2</channelType>
        <channelFunc>conFig</channelFunc>
        <eu>myFunc 2</eu>
        <custScale>myFunc 2</custScale>
        <rawMin>myFunc 2</rawMin>
        <rawMax>myFunc 2</rawMax>
        <euMin>myFunc 2</euMin>
        <euMax>myFunc 2</euMax>
        <dspFormat>myFunc 2</dspFormat>
        <digOfPrec>myFunc 2</digOfPrec>
    </channeles>
</systemConfig>
</systemConfigs>

Now I want to Update Values of the child node where channels ch=4

where After Update only the node channels with attribute ch=4 will be saved with new values like this.

<channeles ch="4">
        <chId>4</chId>
        <channelName>Channel New Name</channelName>
        <channelType>New Channel Type</channelType>
        <channelFunc>New Func</channelFunc>
        <eu>New Eu</eu>
        <custScale>New Cust Scale</custScale>
        <rawMin>1</rawMin>
        <rawMax>10</rawMax>
        <euMin>1</euMin>
        <euMax>10</euMax>
        <dspFormat>scintific</dspFormat>
        <digOfPrec>10</digOfPrec>
    </channeles>

I can find the nodes like this way.

$doc = new DOMDocument();
$doc->load(BASEPATH.'data/sysConf.xml');
$selector = new DOMXPath($doc);
$query = '//channeles[@ch="4"]/*';
$list = $selector->query($query);
$node = $list->item(0);

$module = $node->parentNode->getElementsByTagName( "channelName" );
$channelName = $module->item(0)->nodeValue;

$module = $node->parentNode->getElementsByTagName( "channelType" );
$channelType = $module->item(0)->nodeValue;

Please help me with example of code. How can I update my XML node with all child?

Thanks in advance for your help.

Sonnet
  • 79
  • 1
  • 2
  • 7

1 Answers1

-1

Here's a solution using the PHP SimpleXMLElement class and a little XPath:

<?php
$xml = <<<XML
<?xml version="1.0"?>
    <systemConfigs>
        <systemConfig cnfId="1">
        <moduleName>Module 1</moduleName>
        <channeles ch="1">
            <chId>1</chId>
            <channelName>Channel 1 of Module 1</channelName>
            <channelType>myFunc 1</channelType>
            <channelFunc>conFig</channelFunc>
            <eu>myFunc 1</eu>
            <custScale>myFunc 1</custScale>
            <rawMin>myFunc 1</rawMin>
            <rawMax>myFunc 1</rawMax>
            <euMin>myFunc 1</euMin>
            <euMax>myFunc 1</euMax>
            <dspFormat>myFunc 1</dspFormat>
            <digOfPrec>myFunc 1</digOfPrec>
        </channeles>
        <channeles ch="2">
            <chId>2</chId>
            <channelName>Channel 2 of Module 1</channelName>
            <channelType>myFunc 2</channelType>
            <channelFunc>conFig</channelFunc>
            <eu>myFunc 2</eu>
            <custScale>myFunc 2</custScale>
            <rawMin>myFunc 2</rawMin>
            <rawMax>myFunc 2</rawMax>
            <euMin>myFunc 2</euMin>
            <euMax>myFunc 2</euMax>
            <dspFormat>myFunc 2</dspFormat>
            <digOfPrec>myFunc 2</digOfPrec>
        </channeles>
    </systemConfig>
    <systemConfig cnfId="2">
        <moduleName>Module 2</moduleName>
        <channeles ch="3">
            <chId>3</chId>
            <channelName>Channel 1 of Module 2</channelName>
            <channelType>myFunc 1</channelType>
            <channelFunc>conFig</channelFunc>
            <eu>myFunc 1</eu>
            <custScale>myFunc 1</custScale>
            <rawMin>myFunc 1</rawMin>
            <rawMax>myFunc 1</rawMax>
            <euMin>myFunc 1</euMin>
            <euMax>myFunc 1</euMax>
            <dspFormat>myFunc 1</dspFormat>
            <digOfPrec>myFunc 1</digOfPrec>
        </channeles>
        <channeles ch="4">
            <chId>4</chId>
            <channelName>Channel 2 of Module 2</channelName>
            <channelType>myFunc 2</channelType>
            <channelFunc>conFig</channelFunc>
            <eu>myFunc 2</eu>
            <custScale>myFunc 2</custScale>
            <rawMin>myFunc 2</rawMin>
            <rawMax>myFunc 2</rawMax>
            <euMin>myFunc 2</euMin>
            <euMax>myFunc 2</euMax>
            <dspFormat>myFunc 2</dspFormat>
            <digOfPrec>myFunc 2</digOfPrec>
        </channeles>
    </systemConfig>
</systemConfigs>
XML;

// Create the SXE object
// You can read from file using the simplexml_load_file function
$sxe = new SimpleXMLElement($xml); 

// Fetch the right channel using XPath
$channele4 = $sxe->xpath('//channeles[contains(@ch, 4)]');

// Update the values you want
$channele4[0]->channelName = 'Channel New Name';
$channele4[0]->channelType = 'New Channel Type';

// Retrieve the parent (..) node
$systemConfig = $sxe->xpath('//channeles[contains(@ch, 4)]/..');

// Update the moduleName value
$systemConfig[0]->moduleName = 'New module name';

// Store the updated values in the $xml variable
$xml = $sxe->asXML();

// Print the updated XML
echo $xml;

NOTE: In case your loading your XML from an remote source then the instantiation of the SXE object should be done like this:

$url = "http://domain.com/abc.xml";
$sxe = new SimpleXMLElement($url, NULL, TRUE);
Rolando Isidoro
  • 4,983
  • 2
  • 31
  • 43
  • I am getting error, after using simplexml_load_file(FileName.xml) and the error pointing the line $sxe = new SimpleXMLElement($xml); saying that "Start tag expected, '<'" – Sonnet Apr 25 '13 at 01:37
  • I am getting error, after using your code, the error pointing the line $sxe = new SimpleXMLElement($xml); saying that "Start tag expected, '<'" please help. – Sonnet Apr 25 '13 at 01:50
  • Are you sure you copy + pasted my code correctly? See it working here http://codepad.org/gjHpclps. BTW, can you tell me what shows up when you echo the $xml variable right before that line? The SimpleXMLElement constructor expects a valid XML string as the 1st argument, maybe the value you're passing isn't. – Rolando Isidoro Apr 25 '13 at 09:07
  • Thanks I've solved the problem and edited your code above. it is alright now. The line should be like this: $sxe = new SimpleXMLElement($xml,NULL,TRUE); – Sonnet Apr 25 '13 at 21:25
  • That scenario is true when loading XML for external sources and using the URL as 1st argument. I've adjusted the answer, mark it as correct so other people can see it. – Rolando Isidoro Apr 25 '13 at 21:32
  • Would you please help me another thing? I need to update the Sibling (Module 2) of selected node. How can I update. Pleas help. – Sonnet Apr 25 '13 at 21:43
  • Check the modifications I added regarding **Retrieve the parent (..) node** and **Update the moduleName value**. – Rolando Isidoro Apr 25 '13 at 21:57