Microsofts System.Xml.XPath nuget-package,可用於.NET 4.6,聲稱支持XPath 1.0和2.0。 De documentation說descibes命名空間:在System.Xml.XPath中啓用XPath2查詢(XPathException:無效令牌)
System.Xml.XPath命名空間包含定義用於瀏覽和編輯XML信息項的遊標模型的類作爲XQuery 1.0和XPath 2.0數據模型的實例。
升級Visual Studio後,升級和我的所有項目到框架版本4.6我仍然無法獲得最簡單的XPath-2.0 for-expression工作。根據specification,他們應該工作。
我無法想象微軟聲稱支持它實際上不支持的東西,所以顯然我做錯了什麼。 如何正確使用XPath2查詢?
[TestMethod]
public void TestXPath2()
{
// The System.Xml.XPath namespace contains the classes that define a cursor model for navigating and editing XML information items as instances of the
// XQuery 1.0 and XPath 2.0 Data Model.
var expression = "for $x in /Root/Foo/Bar return $x";
var compiledExpression = System.Xml.XPath.XPathExpression.Compile(expression);
// throws XPathException: "for ... has an invalid token"
}
P.S. 其實我是想什麼,是爲了得到這樣的工作:
[TestMethod]
public void TestLibraryForCustomer1()
{
string xmlFromMessage = @"<Library>
<Writer ID=""writer1""><Name>Shakespeare</Name></Writer>
<Writer ID=""writer2""><Name>Tolkien</Name></Writer>
<Book><WriterRef REFID=""writer1"" /><Title>King Lear</Title></Book>
<Book><WriterRef REFID=""writer2"" /><Title>The Hobbit</Title></Book>
<Book><WriterRef REFID=""writer2"" /><Title>Lord of the Rings</Title></Book>
</Library>";
var titleXPathFromConfigurationFile = "./Title";
var writerXPathFromConfigurationFile = "for $curr in . return /Library/Writer[@ID=$curr/WriterRef/@REFID]/Name";
var library = ExtractBooks(xmlFromMessage, titleXPathFromConfigurationFile, writerXPathFromConfigurationFile).ToDictionary(b => b.Key, b => b.Value);
Assert.AreEqual("Shakespeare", library["King Lear"]);
Assert.AreEqual("Tolkien", library["The Hobbit"]);
Assert.AreEqual("Tolkien", library["Lord of the Rings"]);
}
[TestMethod]
public void TestLibraryForCustomer2()
{
string xmlFromMessage = @"<Library>
<Writer ID=""writer1"">
<Name>Shakespeare</Name>
<Book><Title>Sonnet 18</Title></Book>
</Writer>
<Writer ID=""writer2"">
<Name>Tolkien</Name>
<Book><Title>The Hobbit</Title></Book>
<Book><Title>Lord of the Rings</Title></Book>
</Writer>
</Library>";
var titleXPathFromConfigurationFile = "./Title";
var writerXPathFromConfigurationFile = "../Name";
var library = ExtractBooks(xmlFromMessage, titleXPathFromConfigurationFile, writerXPathFromConfigurationFile).ToDictionary(b => b.Key, b => b.Value);
Assert.AreEqual("Shakespeare", library["Sonnet 18"]);
Assert.AreEqual("Tolkien", library["The Hobbit"]);
Assert.AreEqual("Tolkien", library["Lord of the Rings"]);
}
public IEnumerable<KeyValuePair<string,string>> ExtractBooks(string xml, string titleXPath, string writerXPath)
{
var library = XDocument.Parse(xml);
foreach(var book in library.Descendants().Where(d => d.Name == "Book"))
{
var title = book.XPathSelectElement(titleXPath).Value;
var writer = book.XPathSelectElement(writerXPath).Value;
yield return new KeyValuePair<string, string>(title, writer);
}
}
「中的XQuery 1.0和XPath 2.0數據模型」是有關標準的參考 - 這並不意味着xpath 2導航被支持。我無法立即在文檔中找到它只解釋了xpath 1的位置。0支持;如果我能的話,我會把它放在一個答案 – AakashM