3
我正在嘗試使用XPath篩選XML文件。我使用的XPath絕對是對我想要的數據進行過濾,但我不確定如何過濾整個文件。嘗試使用XPath篩選XML
這裏的示例XML文件:
<fields>
<field name='F'>
<field name='0'><value>F.0 stuff</value></field>
<field name='1'><value>F.1 stuff</value></field>
<field name='2'><value>F.2 stuff</value></field>
</field>
<field name='B'>
<field name='0'><value>B.0 stuff</value></field>
<field name='1'><value>B.1 stuff</value></field>
<field name='2'><value>B.2 stuff</value></field>
<field name='3'><value>B.3 stuff</value></field>
</field>
</fields>
下面是所需的輸出:
<fields>
<field name='F'>
<field name='1'><value>F.1 stuff</value></field>
<field name='2'><value>F.2 stuff</value></field>
</field>
<field name='B'>
<field name='3'><value>B.3 stuff</value></field>
</field>
</fields>
的解決方案並不一定要與XPath來解決,但由於這是一個.NET應用程序, .NET API將不勝感激!以下代碼可以被剪切並粘貼到LINQPad中,無需編輯即可查看我正在嘗試執行的操作。
var doc = XDocument.Parse(@"
<fields>
<field name='F'>
<field name='0'><value>F.0 stuff</value></field>
<field name='1'><value>F.1 stuff</value></field>
<field name='2'><value>F.2 stuff</value></field>
</field>
<field name='B'>
<field name='0'><value>B.0 stuff</value></field>
<field name='1'><value>B.1 stuff</value></field>
<field name='2'><value>B.2 stuff</value></field>
<field name='3'><value>B.3 stuff</value></field>
</field>
</fields>");
doc.Dump("Original XML");
var xpath = "//fields/field[@name='F']/field[@name='1' or @name='2'] | //fields/field[@name='B']/field[@name='3']";
doc.XPathSelectElements(xpath).Dump("XPath Combined");
var desired = XDocument.Parse(@"
<fields>
<field name='F'>
<field name='1'><value>F.1 stuff</value></field>
<field name='2'><value>F.2 stuff</value></field>
</field>
<field name='B'>
<field name='3'><value>B.3 stuff</value></field>
</field>
</fields>");
desired.Dump("Desired Filtered XML");
編輯:我完全錯過了XML轉換 - 謝謝你的解決方案!這裏是你可以粘貼到LINQPad看到它的工作解決方案:
var filterString = @"@name=""F""]/field[@name=""0""] | field[@name=""B""]/field[not(@name=""3"")";
var xslFmt = @"
<xsl:stylesheet version='1.0'
xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:output omit-xml-declaration='yes' indent='yes'/>
<xsl:template match='node()|@*'>
<xsl:copy>
<xsl:apply-templates select='node()|@*'/>
</xsl:copy>
</xsl:template>
<xsl:template match=
'field[{0}]
'/>
</xsl:stylesheet>";
var xslMarkup = string.Format(xslFmt, filterString);
var xmlTree = XDocument.Parse(@"
<fields>
<field name='F'>
<field name='0'><value>F.0 stuff</value></field>
<field name='1'><value>F.1 stuff</value></field>
<field name='2'><value>F.2 stuff</value></field>
</field>
<field name='B'>
<field name='0'><value>B.0 stuff</value></field>
<field name='1'><value>B.1 stuff</value></field>
<field name='2'><value>B.2 stuff</value></field>
<field name='3'><value>B.3 stuff</value></field>
</field>
</fields>");
xmlTree.Dump("Original XML");
// Code from MSDN: http://msdn.microsoft.com/en-us/library/bb675186.aspx
var newTree = new XDocument();
using (var writer = newTree.CreateWriter()) {
// Load the style sheet.
var xslt = new XslCompiledTransform();
xslt.Load(XmlReader.Create(new StringReader(xslMarkup)));
// Execute the transform and output the results to a writer.
xslt.Transform(xmlTree.CreateReader(), writer);
}
newTree.Dump("Transformed XML");
什麼是標準從你的原始XML獲取「已過濾」的一個?你想看哪個XML節點,你想「過濾」出哪個? – 2010-09-28 20:28:57
XSLT在這裏是正確的答案嗎? – 2010-09-28 20:30:12
非常詳細的問題,但它仍然不是很清楚如何從輸入到輸出。什麼標準適用? – 2010-09-28 20:31:38