以下是一个示例XML文档,它与我从中获取信息的文档相匹配:
<?xml version="1.0" standalone="yes"?>
<Products xmlns="http://tempuri.org/Products.xsd">
<Movies>
<Title>Title1</Title>
<Language>English</Language>
</Movies>
<Movies>
<Title>Title2</Title>
<Language>English</Language>
</Movies>
<Movies>
<Title>Title3</Title>
<Language>French</Language>
</Movies>
<Books>
<Title>BTitle1</Title>
<Genre>Suspense</Genre>
</Books>
<Books>
<Title>BTitle2</Title>
<Genre>Suspense</Genre>
</Books>
<Books>
<Title>BTitle3</Title>
<Genre>SciFi</Genre>
</Books>
<Books>
<Title>BTitle4</Title>
<Genre>SciFi</Genre>
</Books>
</Products>
这是我的代码,以获取所有具有悬疑类型的书籍:
//Get state list using XPath
XPathDocument xDoc = new XPathDocument(xmlPath); //Path to my file
XPathNavigator xNav = xDoc.CreateNavigator();
string booksQuery = "Books[Genre = \"Suspense\"]";
XPathNodeIterator xIter = xNav.Select(booksQuery);
while (xIter.MoveNext())
{
//do stuff with xIter.Current
}
我尝试过多次查询,包括Products/Books[Genre = \"Suspense\"]
,Products/Books
,./Books
和Books
。我的xIter始终没有任何项目。
我是XPath的新手,所以我确定这是一个非常简单的错误,但也许不是。我知道我可以使用myDataSet.ReadXml(myXmlPathString);
从这个XML文件中获取带有[Movies]和[Books]表的DataSet,因此XML文件没有损坏。如果这有帮助。
所以,我的问题......我做错了什么?
答案 0 :(得分:10)
XPathDocument xDoc = new XPathDocument(xmlPath); //Path to my file
XPathNavigator xNav = xDoc.CreateNavigator();
XmlNamespaceManager mngr = new XmlNamespaceManager(xNav.NameTable);
mngr.AddNamespace("p", "http://tempuri.org/Products.xsd");
string booksQuery = "//p:Books[p:Genre = \"Suspense\"]";
XPathNodeIterator xIter = xNav.Select(booksQuery,mngr);
答案 1 :(得分:6)
您正在寻找名为Books的元素,该元素不在命名空间中。 Products
元素正在为该元素及其所有后代设置默认命名空间。您需要在XPath中使用命名空间...或使用不同的方法进行查询,例如LINQ to XML。 (我个人认为LINQ to XML 很多比XPath更容易处理 - 特别是当你需要涉及名称空间时。)
答案 2 :(得分:2)
正如乔恩所说,你错过了一个命名空间。
您可以在C#中执行以下操作
//Get state list using XPath
XPathDocument xDoc = new XPathDocument(xmlPath); //Path to my file
XPathNavigator xNav = xDoc.CreateNavigator();
XmlNamespaceManager xmlns = new XmlNamespaceManager(xNav.NameTable);
xmlns.AddNamespace("p", "http://tempuri.org/Products.xsd");
string booksQuery = "//p:Books[p:Genre = 'Suspense']";
XPathNodeIterator xIter = xNav.Select(booksQuery, xmlns);
while (xIter.MoveNext())
{
//do stuff with xIter.Current
}
答案 3 :(得分:0)
使用VTD-XML,命名空间更简单...您可以选择是否忽略命名空间。
VTDGen vg = new VTDGen();
if(vg.parseFile("product.xml",true)){
VTDNav vn = vg.getNav();
AutoPilot ap = new AutoPilot(vn);
ap.selectXPath("Produt[Genre='suspence']");
int i = -1;
while ((i = ap.evalXPath()) != -1)
{
// processing logic
}
}