在删除元素的同一行插入XML元素


Insert XML element on the same line of deleted element

我有一个php文档,它根据属性"id"的值删除一个XML元素(带子元素),然后创建一个具有相同子元素的新元素,但从表单输入添加了不同的文本:

<?php
function ctr($myXML, $id) {
    $xmlDoc = new DOMDocument();
    $xmlDoc->load($myXML);
    $xpath = new DOMXpath($xmlDoc);
    $nodeList = $xpath->query('//noteboard[@id="'.$id.'"]');
    if ($nodeList->length) {
        $node = $nodeList->item(0);
        $node->parentNode->removeChild($node);
    }
    $xmlDoc->save($myXML);
}
$xml = 'xml.xml'; // file
$to = $_POST['eAttr'];// the attribute value for "id"
ctr($xml,$to);

$target = "3";
$newline = "
<noteboard id='".$_POST['eId']."'>
    <noteTitle>".$_POST['eTitle']."</noteTitle>
    <noteMessage>".$_POST['eMessage']."</noteMessage>
    <logo>".$_POST['eType']."</logo>
</noteboard>"; // HERE
$stats = file($xml, FILE_IGNORE_NEW_LINES);   
$offset = array_search($target,$stats) +1;
array_splice($stats, $offset, 0, $newline);   
file_put_contents($xml, join("'n", $stats));   
?>

XML.xml

<note>
<noteboard id="title">
    <noteTitle>Title Text Here</noteTitle>
    <noteMessage>Text Here</noteMessage>
    <logo>logo.jpg</logo>
 </noteboard>
 </note>

这工作得很好,但我希望它将新的XML内容放在旧元素(已删除)曾经所在的行上,而不是$target将其添加到第3行。它应该看起来像元素被"编辑",但它不会实现这一点,如果它是在错误的行。

XML文档中的行并不是完全相关的,它们只是格式化,以便文档更容易(由人)阅读。把它想象成一棵结点树。不仅元素是节点,还包括任何内容,如XML声明属性和任何文本。

记住这一点,你可以把你的问题看作是替换一个元素节点。

首先创建新的noteCard元素。这可以封装成一个函数:

function createNote(DOMDocument $document, $id, array $data) {
  $noteboard = $document->createElement('notecard');
  $noteboard->setAttribute('id', $id);
  $noteboard
    ->appendChild($document->createElement('noteTitle'))
    ->appendChild($document->createTextNode($data['title']));
  $noteboard
    ->appendChild($document->createElement('noteMessage'))
    ->appendChild($document->createTextNode($data['text']));
  $noteboard
    ->appendChild($document->createElement('logo'))
    ->appendChild($document->createTextNode($data['logo']));
  return $noteboard;
}

调用函数来创建新的notecard元素节点。我在这里使用字符串字面量,你必须用你的表单中的变量来替换它。

$newNoteCard = createNote(
  $document, 
  42,
  [
    'title' => 'New Title',
    'text' => 'New Text',
    'logo' => 'newlogo.svg',
  ] 
); 

现在你有了新的notecard,你可以搜索现有的并替换它:

foreach($xpath->evaluate('//noteboard[@id=3][1]') as $noteboard) {
  $noteboard->parentNode->replaceChild($newNoteCard, $noteboard);
}

完整的示例:

$document = new DOMDocument();
$document->formatOutput = true;
$document->preserveWhiteSpace = false;
$document->loadXml($xml);
$xpath = new DOMXpath($document);
function createNote(DOMDocument $document, $id, array $data) {
  $noteboard = $document->createElement('notecard');
  $noteboard->setAttribute('id', $id);
  $noteboard
    ->appendChild($document->createElement('noteTitle'))
    ->appendChild($document->createTextNode($data['title']));
  $noteboard
    ->appendChild($document->createElement('noteMessage'))
    ->appendChild($document->createTextNode($data['text']));
  $noteboard
    ->appendChild($document->createElement('logo'))
    ->appendChild($document->createTextNode($data['logo']));
  return $noteboard;
}
$newNoteCard = createNote(
  $document, 
  42,
  [
    'title' => 'New Title',
    'text' => 'New Text',
    'logo' => 'newlogo.svg',
  ] 
); 
foreach($xpath->evaluate('//noteboard[@id=3][1]') as $noteboard) {
  $noteboard->parentNode->replaceChild($newNoteCard, $noteboard);
}
echo $document->saveXml();