我正在尝试使用XPath过滤Xml文档,使其成为自身的子集。
我已经使用XPath获取XmlNodeList,但我需要将其转换为XML文档。
有没有办法将XMLNodeList转换为XmlDocument或通过直接过滤另一个XmlDocument来生成XmlDocument?
答案 0 :(得分:4)
使用XmlDocument,您需要将这些节点导入第二个文档;
XmlDocument doc = new XmlDocument();
XmlElement root = (XmlElement)doc.AppendChild(doc.CreateElement("root"));
XmlNodeList list = // your query
foreach (XmlElement child in list)
{
root.AppendChild(doc.ImportNode(child, true));
}
答案 1 :(得分:1)
这是使用XSLT的一个非常典型的原因,XSLT是一种将一个XML文档转换为另一个XML文档(或转换为HTML或文本)的高效且强大的工具。
这是执行XSLT转换并将结果发送到控制台的最小程序:
using System;
using System.Xml;
using System.Xml.Xsl;
namespace XsltTest
{
class Program
{
static void Main(string[] args)
{
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load("test.xslt");
XmlWriter xw = XmlWriter.Create(Console.Out);
xslt.Transform("input.xml", xw);
xw.Flush();
xw.Close();
Console.ReadKey();
}
}
}
这是实际的XSLT,它保存在程序目录的test.xslt
中。这很简单:给定一个顶级元素名为input
的输入文档,它会创建一个output
元素并复制到value
属性设置为true
的每个子元素上}。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/input">
<output>
<xsl:apply-templates select="*[@value='true']"/>
</output>
</xsl:template>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这里是input.xml
:
<?xml version="1.0" encoding="utf-8" ?>
<input>
<element value="true">
<p>This will get copied to the output.</p>
<p>Note that the use of the identity transform means that all of this content
gets copied to the output simply because templates were applied to the
<em>element</em> element.
</p>
</element>
<element value="false">
<p>This, on the other hand, won't get copied to the output.</p>
</element>
</input>
答案 2 :(得分:0)
我实际上只想到了一种方法,但它似乎并不优雅。
使用StringBuilder组合XmlNodeList中每个XmlNodes的OuterXml ...
正如我所说,它不够优雅,但我认为它可能会奏效。我很感激任何其他建议...