C # XPath help - выражение не работает - PullRequest
6 голосов
/ 18 января 2011

Вот пример 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>

Вот мой код, чтобы получить все книги с жанром Suspense:

//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, поэтому я уверен, что это действительно простая ошибка, но, возможно, нет.Я знаю, что могу получить DataSet с таблицами [Фильмы] и [Книги] из этого XML-файла, используя myDataSet.ReadXml(myXmlPathString);, поэтому XML-файл не поврежден.Если это поможет.

Итак, мой вопрос ... что я делаю не так?

Ответы [ 4 ]

10 голосов
/ 18 января 2011
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);
6 голосов
/ 18 января 2011

Вы ищете элемент с именем Books, которого нет в пространстве имен.Элемент Products устанавливает пространство имен по умолчанию для этого элемента и всех его потомков.Вам нужно будет использовать пространство имен в вашем XPath ... или использовать другой подход для запросов, такой как LINQ to XML.(Лично я считаю, что с LINQ to XML намного легче работать, чем с XPath, особенно когда вам нужно задействовать пространства имен.)

2 голосов
/ 18 января 2011

Как сказал Джон, вам не хватает пространства имен.

Вы можете сделать это в 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
}
0 голосов
/ 18 января 2011

С 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
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...