考虑以下xml:
<div>
<a href="http://www.google.com/">This is:</a>
<p>A test... <b>1</b><i>2</i><u>3</u></p>
<p>This too</p>
Finished.
</div>
此xml的内容位于System.Xml.XmlDocument
实例中。我需要替换所有p
元素,并在每个段落元素后添加一个中断。我写了以下代码:
var pElement = xmlDocument.SelectSingleNode("//p");
while (pElement != null)
{
var textNode = xmlDocument.CreateTextNode("");
foreach (XmlNode child in pElement.ChildNodes)
{
textNode.AppendChild(child);
}
textNode.AppendChild(xmlDocument.CreateElement("br"));
pElement.ParentNode.ReplaceChild(pElement, textNode);
pElement = xmlDocument.SelectSingleNode("//p");
}
我正在创建一个空节点并将每个段落节点的子节点添加到它。不幸的是,这不起作用:文本节点不能包含元素。
如何实现此替换的任何想法?
答案 0 :(得分:1)
看起来我找到了使用InsertAfter
方法的解决方案:
var pElement = xmlDocument.SelectSingleNode("//p");
while (pElement != null)
{
//store position where new elements need to be added
var position = pElement;
while(pElement.FirstChild != null)
{
var child = pElement.FirstChild;
position.ParentNode.InsertAfter(child, position);
//store the added child as position for next child
position = child;
}
//add break
position.ParentNode.InsertAfter(xmlDocument.CreateElement("br"), position);
//remove empty p
pElement.ParentNode.RemoveChild(pElement);
//select next p
pElement = xmlDocument.SelectSingleNode("//p");
}
这个想法如下:
p
个节点。p
。p
节点后添加一个中断。p
元素。找到这个位置非常棘手。需要使用p
InsertAfter
作为位置元素,将第一个子节点添加到p
的父节点。但是下一个孩子需要在之前添加的孩子之后添加。解决方案:保存其位置并使用它。
注意:在for each
集合上使用pElement.ChildNodes
迭代器将不起作用,因为在移动了一半节点后,迭代器会确定它已完成。看起来它使用某种计数而不是对象集合。
答案 1 :(得分:0)
修改内存中的XmlDocument
个对象是有问题的 - 请参阅类似问题here。
最简单的方法是使用XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="p">
<xsl:copy-of select="node()"/>
<br/>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
然后您可以使用XmlDocument
类将其应用于XslCompiledTransform
,并使用输出XML生成字符串或流。
答案 2 :(得分:0)
如果我理解你想要实现的目标,你可以尝试以下方式:
foreach (XmlNode node in doc.SelectNodes("//p"))
{
node.ParentNode.InsertAfter(doc.CreateElement("br"), node);
}
如果我不理解,也许你可以发布你想要实现的输出。