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

时间:2015-07-20 08:19:41

标签: php xml

我有一个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行。看起来该元素正在被“编辑”,但如果它在错误的行上则无法实现。

1 个答案:

答案 0 :(得分:1)

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();