6 votes

Aide pour C# XPath - Expression ne fonctionne pas

Voici un exemple de document XML qui correspond à celui dont je tire des informations :

<?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>

Voici mon code pour obtenir tous les livres du genre 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
}

J'ai essayé plusieurs requêtes dont Products/Books[Genre = \"Suspense\"] , Products/Books , ./Books y Books . Mon xIter a toujours zéro élément.

Je suis nouveau dans XPath, donc je suis sûr que c'est une erreur très simple, mais peut-être pas. Je sais que je peux obtenir un DataSet avec les tables [Movies] et [Books] à partir de ce fichier XML en utilisant la méthode suivante myDataSet.ReadXml(myXmlPathString); donc le fichier XML n'est pas corrompu. Si cela peut vous aider.

Donc, ma question... qu'est-ce que je fais mal ?

10voto

theChrisKent Points 10963
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);

6voto

Jon Skeet Points 692016

Vous cherchez un élément appelé Books qui n'est pas dans un espace de nom. Le site Products définit l'espace de noms par défaut pour cet élément et tous ses descendants. Vous devrez utiliser un espace de noms dans votre XPath... ou utiliser une approche différente pour l'interrogation, comme LINQ to XML. (Personnellement, je trouve que LINQ to XML beaucoup plus facile à gérer que XPath - surtout lorsque vous devez faire intervenir des espaces de noms).

2voto

Andy Skirrow Points 1538

Comme Jon l'a dit, il vous manque un espace de nom.

Vous pouvez le faire en C# comme suit

//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
}

0voto

vtd-xml-author Points 891

Avec VTD-XML, l'espace de noms est beaucoup plus simple... vous pouvez choisir d'ignorer ou non l'espace de noms.

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
   }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X