我正在尝试将元素插入到某些文本周围的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>
我可以将标头的值设置为字符串,但<>
转换为<
和>
,这是不行的。现在我正在使用$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>
然后再次打开文件并移动元素。或者搜索并替换&amp; lt和&amp; gt。这似乎是错误的方式。
这可以用simpleXML吗?
谢谢!
答案 0 :(得分:0)
从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>