替换部分XML节点值

时间:2012-07-03 12:26:31

标签: php xml

我试图用另一个值替换xml节点值的一部分。例如,我在我的xml中使用了这个节点:

<eerste_kwartier>naam leeg</eerste_kwartier>

或者例如:

<eerste_kwartier>leeg leeg</eerste_kwartier>

在第一个例子中,我想要替换&#39; leeg&#39;价值与其他东西。在第二个我只想取代第一个&#39; leeg&#39;价值与其他东西。有什么想法我应该这样做吗?

提前致谢,

Jan Thiemen

3 个答案:

答案 0 :(得分:1)

执行此操作的正确方法是使用PHP的DOMDocument类来提取所需内容。这是一个有效的解决方案:

$str = '<eerste_kwartier>naam leeg</eerste_kwartier>';

$doc = new DOMDocument();
$fragment = $doc->createDocumentFragment();
$fragment->appendXML( $str);
$doc->appendChild( $fragment);

$xpath = new DOMXPath( $doc);
$node = $xpath->query( '/eerste_kwartier')->item(0);

$text = $doc->createTextNode( $node->textContent);
$node->nodeValue = ''; // Clear out the contents of the tag

// Get the text before and after the replacement
$start = strpos( $text->wholeText, 'leeg');
$before = $text->substringData( 0, $start);
$after = $text->substringData( $start + strlen( 'leeg'), strlen( $text->wholeText));

// Put the text back, minus the replacement, with something else added
$node->appendChild( $doc->createTextNode( trim( $before)));
$node->appendChild( $doc->createTextNode( "Something Else"));
$node->appendChild( $doc->createTextNode( $after));

echo htmlentities( $doc->saveXML());

outputs

<?xml version="1.0"?> <eerste_kwartier>naam Something Else</eerste_kwartier> 

对于第二个测试用例,它是will output

<?xml version="1.0"?> <eerste_kwartier>Something Else leeg</eerste_kwartier> 

答案 1 :(得分:0)

基本上,您可以使用DOM使用PHP实现此目的。

在字符串中给出XML格式:

    $xml = <<<EOX
<root>    
  <eerste_kwartier>naam leeg</eerste_kwartier>
  <eerste_kwartier>leeg leeg</eerste_kwartier>
</root>
EOX;

你可以做以下事情:

1 - 使用PHP和DOM

使用DOM,您可以使用getElementsByTagName()方法获取具有相同标记名称的元素列表,遍历该列表并应用您喜欢的文本转换。

示例:

// Load source XML
$xmlObj = new DOMDocument("1.0", "UTF-8");
$xmlObj->loadXML($xml);

// Obtain interesting nodes into a node list object
$nodeList = $xmlObj->getElementsByTagName('eerste_kwartier');

// Prepare destination XML object
$xmlObjResult = new DOMDocument("1.0", "UTF-8");
$rootElement = $xmlObjResult->createElement("root");

// Walk node list
for ($i = 0; $i < $nodeList->length; $i++) {
  $tmp = $nodeList->item($i)->nodeValue;
  // Use regular expressions for greater flexibility in selecting text to replace
  $tmp = preg_replace('/naam/', 'leeg', $tmp);
  // Prepare destination element
  $eerste_kwartier = $xmlObjResult->createElement("eerste_kwartier");
  $cdata = $xmlObjResult->createCDATASection($tmp);
  $eerste_kwartier->appendChild($cdata);
  $rootElement->appendChild($eerste_kwartier);
}

// Append root element to the document
$xmlObjResult->appendChild($rootElement);

// Enjoy your XML
echo $xmlObjResult->saveXML();

2 - 使用PHP和DOMXPath

上面的示例可以很容易地更改为使用XPath的query()而不是DOM的getElementsByTagName()。

所以你会这样做:

// Load source XML
$xmlObj = new DOMDocument("1.0", "UTF-8");
$xmlObj->loadXML($xml);

// Obtain interesting nodes into a node list object
$xpath = new DOMXPath($xmlObj);
$nodeList = $xpath->query("//eerste_kwartier");

// Prepare destination XML object
$xmlObjResult = new DOMDocument("1.0", "UTF-8");
$rootElement = $xmlObjResult->createElement("root");

// Walk node list
for ($i = 0; $i < $nodeList->length; $i++) {
  $tmp = $nodeList->item($i)->nodeValue;
  // Use regular expressions for greater flexibility in selecting text to replace
  $tmp = preg_replace('/naam/', 'leeg', $tmp);
  // Prepare destination element
  $eerste_kwartier = $xmlObjResult->createElement("eerste_kwartier");
  $cdata = $xmlObjResult->createCDATASection($tmp);
  $eerste_kwartier->appendChild($cdata);
  $rootElement->appendChild($eerste_kwartier);
}

// Append root element to the document
$xmlObjResult->appendChild($rootElement);

// Enjoy your XML
echo $xmlObjResult->saveXML();

结论

正如你当然注意到这两个选项非常相似。

如果您在文档中的搜索解析为搜索相同的标记名称,我建议使用选项1;如果您的搜索应该比这更清晰,我建议选项2,因为XPath有很多很好的武器来对抗XML搜索 - 复杂性(可以找到XPath的简要介绍here,但是有很多可用的材料只是谷歌搜索)。

我不会让XSL进入图片,除非你应该对你的内容应用更高规模和明确的转换,但以防万一:http://htmlite.com/XML008.php(一个非常简短的XSLT介绍教程,它应该引起你的胃口)。

答案 2 :(得分:-1)

你不能使用str_replace函数吗?

$xml = str_replace('<eerste_kwartier>leeg leeg</eerste_kwartier>','<eerste_kwartier>somethingelse leeg</eerste_kwartier>',$xml);