这里不是一个大的XML专家...说我有一个更大的文档的Xml节点,看起来像这样:
<TopLevel>
<Element1>...</Element1>
<Element2>...</Element2>
<Element3>
<Sub1>abc</Sub1>
<Sub2>def</Sub2>
</Element3>
<Element3>
<Sub1>ghi</Sub1>
<Sub2>jkl</Sub2>
</Element3>
<Element3>
<Sub1>mno</Sub1>
<Sub2>pqr</Sub2>
</Element3>
</TopLevel>
(Element3可以重复无限次) 我想结束三个节点,如下所示:
<TopLevel>
<Element1>...</Element1>
<Element2>...</Element2>
<Element3>
<Sub1>abc</Sub1>
<Sub2>def</Sub2>
</Element3>
</TopLevel>
<TopLevel>
<Element1>...</Element1>
<Element2>...</Element2>
<Element3>
<Sub1>ghi</Sub1>
<Sub2>jkl</Sub2>
</Element3>
</TopLevel>
<TopLevel>
<Element1>...</Element1>
<Element2>...</Element2>
<Element3>
<Sub1>mno</Sub1>
<Sub2>pqr</Sub2>
</Element3>
</TopLevel>
如果我知道Element3只能重复两次我只是克隆节点,从原始节点中删除第一个实例,从克隆节点和InsertAfter中删除第二个实例,但我不知道如何做到未知数量的元素......
谢谢!
答案 0 :(得分:2)
如果XSLT是您的选项,那么以下样式表
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="utf-8" indent="yes"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/TopLevel">
<root>
<xsl:apply-templates select="Element3"/>
</root>
</xsl:template>
<xsl:template match="Element3">
<TopLevel>
<xsl:apply-templates select="../Element1|../Element2"/>
<xsl:call-template name="identity"/>
</TopLevel>
</xsl:template>
</xsl:stylesheet>
产生以下输出(我格式化):
<root>
<TopLevel>
<Element1>...</Element1>
<Element2>...</Element2>
<Element3>
<Sub1>abc</Sub1>
<Sub2>def</Sub2>
</Element3>
</TopLevel>
<TopLevel>
<Element1>...</Element1>
<Element2>...</Element2>
<Element3>
<Sub1>ghi</Sub1>
<Sub2>jkl</Sub2>
</Element3>
</TopLevel>
<TopLevel>
<Element1>...</Element1>
<Element2>...</Element2>
<Element3>
<Sub1>...</Sub1>
<Sub2>...</Sub2>
</Element3>
</TopLevel>
</root>
您提供的输出是文档片段;我添加了一个root
元素,以便它可以作为常规文档加载。但是XSLT也会在没有根元素的情况下发出这个。
答案 1 :(得分:1)
XML标准只允许单个顶级节点,因此您需要一个围绕所有<TopLevel>
的包装器。取决于您的输出消耗量可能或不重要。
XDocument input; //Fill this in somehow
XElement top = input.Element("TopLevel");
XElement elem1 = top.Element("Element1");
XElement elem2 = top.Element("Element2");
XDocument output = new XDocument(); //You may need to do additional initialization here
foreach (XElement elem3 in top.Elements("Element3");
{
output.Add(new XElement("TopLevel", elem1, elem2, elem3));
}
自从我生成输出文件以来已经有一段时间了,所以如果我的语法不是100%正确,我很抱歉。
答案 2 :(得分:0)
这样的东西?
string fromXml =
@"
<TopLevel>
<Element1>...</Element1>
<Element2>...</Element2>
<Element3>
<Sub1>abc</Sub1>
<Sub2>def</Sub2>
</Element3>
<Element3>
<Sub1>ghi</Sub1>
<Sub2>jkl</Sub2>
</Element3>
<Element3>
<Sub1>...</Sub1>
<Sub2>...</Sub2>
</Element3>
</TopLevel>
";
XElement from = XElement.Parse(fromXml);
XElement root = new XElement("Root");
foreach (var node in from.Descendants("Element3"))
{
XElement toplevel = new XElement("TopLevel");
toplevel.Add(from.Element("Element1"));
toplevel.Add(from.Element("Element2"));
toplevel.Add(node);
root.Add(toplevel);
}
var final = root.Nodes().Aggregate("",((s,n)=>s+=n.ToString()+"\n"));