Я пытаюсь отфильтровать документ Xml таким образом в подмножество себя, используя XPath.
Я использовал XPath для получения XmlNodeList, но мне нужно преобразовать это в XML-документ.
Есть ли способ преобразовать XMLNodeList в XmlDocument или создать XmlDocument, напрямую связав другой XmlDocument?
С 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));
}
Это довольно типичная причина использования XSLT, который является эффективным и мощным инструментом для преобразования одного документа 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>
Я действительно подумал о том, как это сделать, но это не кажется очень элегантным.
используйте StringBuilder для объединения OuterXml каждого из XmlNodes в XmlNodeList...
Как я сказал, это неэлегантно, но я думаю, что это может сработать. Я был бы признателен за любое другое предложение...