使用php替换xml中的特定节点值

Posted

技术标签:

【中文标题】使用php替换xml中的特定节点值【英文标题】:Replace specific node value in xml using php 【发布时间】:2013-12-30 16:37:07 【问题描述】:

您好,我正在解析多个 xml 提要并将其合并为一个,它对我来说工作正常,但现在我有点卡在某一点上,因为我需要在特定节点值中添加一些前缀,我的意思是我需要更改那个节点。在这里,我提供了一些我想要的示例代码。

XML

<JobRecords>
    <JobRecord>
        <Brand>Corporate1</Brand>
        <JobId>45982</JobId>
        <WorkTypes>
            <WorkTypeRecord>
                <Title>Permanent1</Title>
            </WorkTypeRecord>
        </WorkTypes>
    </JobRecord>
    <JobRecord>
        <Brand>Corporate2</Brand>
        <JobId>45983</JobId>
        <WorkTypes>
            <WorkTypeRecord>
                <Title>Permanent2</Title>
            </WorkTypeRecord>
        </WorkTypes>
    </JobRecord>
    <JobRecord>
        <Brand>Corporate3</Brand>
        <JobId>45984</JobId>
        <WorkTypes>
            <WorkTypeRecord>
                <Title>Permanent3</Title>
            </WorkTypeRecord>
        </WorkTypes>
    </JobRecord>
</JobRecords>    

在上面的 xml 中,我想添加这样的前缀 &lt;JobId&gt;0-45984&lt;/JobId&gt;

这里是 php 代码,它将不同的 xml 提要组合成一个输出,如上所示。

<?php 
    $feed1 = "data1.xml";
    $feed2 = "data2.xml"; 
    $feed3 = "data3.xml";

    $xml1 = new DOMDocument('1.0', 'UTF-8');
    $xml1->load($feed1);

    $xml2 = new DOMDocument('1.0', 'UTF-8');
    $xml2->load($feed2);

    $xml3 = new DOMDocument('1.0', 'UTF-8');
    $xml3->load($feed3);

    $addXml = array();
    $addXml[] = $xml1->saveXML();
    $addXml[] = $xml2->saveXML();
    $addXml[] = $xml3->saveXML();

    // create a new document
    $dom = new DOMDocument();
    $dom->appendChild($dom->createElement('JobRecords'));

    foreach ($addXml as $xml) 
      $addDom = new DOMDocument();
      $addDom->loadXml($xml);
      if ($addDom->documentElement) 
        foreach ($addDom->documentElement->childNodes as $node) 
          $dom->documentElement->appendChild(
            $dom->importNode($node, TRUE)
          );
        
      
    

    $xmlFinal = $dom->saveXml();
    echo $xmlFinal;
?>  

到目前为止我已经尝试过但没有成功请告诉我如何实现这一目标。 提前致谢,非常感谢。

【问题讨论】:

【参考方案1】:

您可以从根目录迭代并检查和替换节点,如下所示。这里$xmlData 保存了你的xml 字符串。

$dom = new DOMDocument();
$dom->loadXML($xmlData);
foreach ($dom->documentElement->childNodes as $node) 
//print_r($node);
if($node->nodeType==1)
   $OldJobId = $node->getElementsByTagName('JobId')->Item(0);
   $newelement = $dom->createElement('JobId','0-'.$OldJobId->nodeValue); 
    $OldJobId->parentNode->replaceChild($newelement, $OldJobId);
 

$str = $dom->saveXML($dom->documentElement);
echo $str;

你可以找到工作演示here

【讨论】:

【参考方案2】:

我不确定您为什么不直接在循环内加载 xml 提要,就像在 previous answer 的第二个示例中一样。

将'JobRecord'元素导入目标,文档后,你必须找到它的JobId child并修改它的nodeValue属性

$files= array(
  'xml1.xml',
  'xml2.xml',
  'xml3.xml'
  // ... more xmls
);

$dom = new DOMDocument();
$dom->appendChild($dom->createElement('JobRecords'));
// get an xpath object
$xpath = new DOMXpath($dom);

// $index variable for later use
foreach ($files as $index => $filename) 
  $addDom = new DOMDocument();
  $addDom->load($filename);
  if ($addDom->documentElement) 
    foreach ($addDom->documentElement->childNodes as $node) 
      $dom->documentElement->appendChild(
        $record = $dom->importNode($node, TRUE)
      );
      // find the jobId child elements (should be only one)
      $jobIds = $xpath->evaluate('./JobId', $record);
      foreach ($jobIds as $jobId) 
        // prefix the value with the index
        $jobId->nodeValue = $index.'-'.$jobId->nodeValue;
      
    
  


echo $dom->saveXml();

【讨论】:

这个答案没有任何反应,请你再看看你的答案。 嗨,我已经尝试过上面的代码,但上面的代码人没有任何反应。 jobId 的值根本没有改变。 它工作得很好。我在本地测试过。 eval.in/78610(改为使用xml文本)。 如果您检查示例,您应该会看到不同之处。使用 DOMDocument::loadXml() 加载 xml 字符串,使用 DOMDocument::load() 加载 xml 文件。

以上是关于使用php替换xml中的特定节点值的主要内容,如果未能解决你的问题,请参考以下文章

在 PHP 中显示特定的 XML 节点

替换VB6中的XML节点中的值

使用 R 的 xmlEventParse 存储特定的 XML 节点值

如何根据节点值使用php删除xml中的元素[重复]

Powershell 中非常大的 XML 文件

如何遍历任何 XML 并使用 XSLT 替换特定值