【发布时间】:2017-10-11 12:29:39
【问题描述】:
我正在编写使用 XPath 查询解析 XML 文件的类。 XML 可能看起来有点像这样:
<?xml version="1.0" encoding="UTF-8"?>
<Doc>
<Name id="aa">Alice</Name>
<Name id="bb">Bob</Name>
<Name id="cc">Candice</Name>
<Person nameid="aa"></Person>
<Person nameid="bb"></Person>
<Person nameid="aa"></Person>
</Doc>
想要的输出是:
Alice
Bob
Alice
我正在使用 C# 来解析人物:
// these are dynanically defined elsewhere.
const string personXPath = "/Doc/Person";
const string nameXPath = "/Doc/Name[@id=current()/@nameid]"; // <== modify this line
void ParseXDocument(XDocument doc)
{
foreach (var personElement in doc.XPathSelectElements(personXPath))
{
var nameElement = personElement.XPathSelectElement(nameXPath);
Console.WriteLine(nameElement.Value);
}
}
这是否可能仅通过修改 nameXPath 变量来实现? (我的软件不应该“知道” XML 结构,唯一将 XML 映射到我自己的类的是 x 路径,它们是可配置的。)
另一个例子:
[TestMethod]
public void TestLibrary()
{
string xmlFromMessage = @"<Library>
<Writer ID=""writer1""><Name>Shakespeare</Name></Writer>
<Writer ID=""writer2""><Name>Tolkien</Name></Writer>
<Book><WriterRef REFID=""writer1"" /><Title>Sonnet 18</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 = "??? what to put here ???";
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);
}
}
【问题讨论】:
-
我认为不可能做你想做的事。您有两个电话
XPathSelectElements因此有两个上下文。所以你需要像我展示的那样传递值。
标签: c# xml xpath xml-parsing lookup