php / simplexml在文本之前和之后添加元素

我试图将元素插入到一些文本周围的xml文档中。 部分问题可能是这不是格式良好的xml,它需要更容易以纯文本形式读取人类。 所以我有这样的东西:

<record>
  <letter>
    <header>To Alice from Bob</header>
    <body>Hi, how is it going?</body>
  </letter>
</record>

我需要结束这个:

<record>
  <letter>
    <header>To <to>Alice</to> from <from>Bob</from></header>
    <body>Hi, how is it going?</body>
  </letter>
</record>

类似的东西应该是有效的html:

<p>To <span>Alice</span> from <span>Bob</span></p>

我可以将标题的值设置为一个字符串,但<>会转换为&lt &gt ,这是不好的。 现在我使用$node->header->addChild('to', 'Alice')$node[0]->header = 'plain text'

如果我做

$node->header->addChild('to', 'Alice'); 
$node->header = 'plain text';
$node->header->addChild('from', 'Bob'); 

然后我得到

<header>plain text <from>Bob</from></header>

'to'被清除。

快速和肮脏的方法是让它成为

<header>plain text <to>Alice</to><from>Bob</from></header>

然后再次打开文件并移动元素。 或者搜索并替换&lt;&gt。 这似乎是错误的方式。

这可能与simpleXML?

谢谢!


从DOM的角度来看(而SimpleXML是最重要的抽象),你不要在文本周围插入元素。 用文本节点和元素节点混合替换文本节点。 SimpleXML在混合子节点上有一些问题,所以你可能想直接使用DOM。 这是一个评论性的例子:

$xml = <<<'XML'
<record>
  <letter>
    <header>To Alice from Bob</header>
    <body>Hi, how is it going?</body>
  </letter>
</record>
XML;

// the words and the tags you would like to create
$words = ['Alice' => 'to', 'Bob' => 'from'];
// a split pattern, you could built this from the array
$pattern = '((Alice|Bob))';

// bootstrap the DOM
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);

// iterate any text node with content
foreach ($xpath->evaluate('//text()[normalize-space() != ""]') as $text) {
  // use the pattern to split the text into an list
  $parts = preg_split($pattern, $text->textContent, -1, PREG_SPLIT_DELIM_CAPTURE);
  // if it was split actually
  if (count($parts) > 1) {
    /// iterate the text parts
    foreach ($parts as $part) {
      // if it is a word from the list
      if (isset($words[$part])) {
        // add the new element node
        $wrap = $text->parentNode->insertBefore(
          $document->createElement($words[$part]),
          $text
        );
        // and add the text as a child node to it
        $wrap->appendChild($document->createTextNode($part));
      } else {
        // otherwise add the text as a new text node
        $text->parentNode->insertBefore(
          $document->createTextNode($part),
          $text
        );
      }
    }
    // remove the original text node
    $text->parentNode->removeChild($text);
  }
}

echo $document->saveXml();

输出:

<?xml version="1.0"?>
<record>
  <letter>
    <header>To <to>Alice</to> from <from>Bob</from></header>
    <body>Hi, how is it going?</body>
  </letter>
</record>
链接地址: http://www.djcxy.com/p/66007.html

上一篇: php/simplexml adding elements before and after text

下一篇: Removing empty elements from xml with regex that matches a sequence twice