【问题标题】:Update XML all child node values search by attribute in PHP [duplicate]在PHP中按属性更新XML所有子节点值搜索[重复]
【发布时间】:2013-04-24 23:08:27
【问题描述】:

我有一个多级节点的 xml。 我可以找到节点,但需要知道如何更新节点值。 在下面的文件中,我可以通过其属性找到节点通道,但是如何更新诸如 channelType 或其他节点的值?

这是我的 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>

现在我想更新通道 ch=4 的子节点的值

在更新后,只有属性 ch=4 的节点通道将被保存为这样的新值。

<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>

我可以这样找到节点。

$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;

请帮助我提供代码示例。如何使用所有子节点更新我的 XML 节点?

提前感谢您的帮助。

【问题讨论】:

    标签: php xml dom xpath


    【解决方案1】:

    这是一个使用 PHP SimpleXMLElement class 和一点 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;
    

    注意:如果您从远程源加载 XML,那么 SXE 对象的实例化应该像这样完成:

    $url = "http://domain.com/abc.xml";
    $sxe = new SimpleXMLElement($url, NULL, TRUE);
    

    【讨论】:

    • 在使用 simplexml_load_file(FileName.xml) 并且错误指向 $sxe = new SimpleXMLElement($xml);说“需要开始标签,'
    • 我收到错误,使用您的代码后,错误指向 $sxe = new SimpleXMLElement($xml);说“需要开始标签,'
    • 你确定你复制+粘贴我的代码正确吗?看到它在这里工作codepad.org/gjHpclps。顺便说一句,你能告诉我当你在该行之前回显 $xml 变量时会出现什么吗? SimpleXMLElement 构造函数需要一个有效的 XML 字符串作为第一个参数,也许您传递的值不是。
    • 谢谢我已经解决了问题并编辑了你上面的代码。现在好了。该行应该是这样的: $sxe = new SimpleXMLElement($xml,NULL,TRUE);
    • 当为外部源加载 XML 并使用 URL 作为第一个参数时,这种情况是正确的。我已经调整了答案,将其标记为正确,以便其他人可以看到。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多