web-dev-qa-db-fra.com

Sélectionnez sur plusieurs critères avec XPath

J'ai un document XML qui ressemble à ceci:

<meadinkent>
 <record>
  <comp_div>MENSWEAR</comp_div> 
  <sty_ret_type>ACCESSORIES</sty_ret_type> 
  <sty_pdt_type>BELTS</sty_pdt_type> 
  <pdt_category>AWESOME_BELTS</pdt_category> 
  </record>
<medinkent>

Je veux utiliser XPath pour sélectionner des nœuds qui correspondent aux quatre éléments et j'ai du mal à obtenir la bonne syntaxe booléenne. J'essaie de faire correspondre les deux premiers juste comme test:

"/meadinkent/record/comp_div[.='" & comp_div & "'] and /meadinkent/record/sty_ret_type[.='" & sty_ret_type & "']"

Ce qui échoue, en disant qu'aucun noeud n'est retourné. Évidemment, je suis très stupide - que fais-je de mal?

À la vôtre, mAtt

27
Matt Thrower

nion
Pour obtenir les deux nœuds, vous devez utiliser l'opérateur union - |

Par exemple, la requête suivante renverra les deux types de nœuds - comp_div et sty_ret_type:

/meadinkent/record/comp_div | /meadinkent/record/sty_ret_type

Filtrer par valeurs de sous-nœuds
Pour filtrer le nœud en fonction de ses valeurs de sous-nœuds, vous devez placer toutes les conditions entre les mêmes crochets [nodeA='value1' and nodeB='value2']

Par exemple, la requête suivante renverra des nœuds d'enregistrement dont les sous-nœuds correspondent au filtre:

/meadinkent/record[comp_div='MENSWEAR' and sty_ret_type='ACCESSORIES']

Un exemple d'union C #:

[Test]
public void UnionExample()
{
    string xml =
        @"<meadinkent>
            <record>
                <comp_div>MENSWEAR</comp_div> 
                <sty_ret_type>ACCESSORIES</sty_ret_type> 
                <sty_pdt_type>BELTS</sty_pdt_type> 
                <pdt_category>AWESOME_BELTS</pdt_category>
            </record>
          </meadinkent>";

    XDocument xDocument = XDocument.Parse(xml);
    IEnumerable<XElement> selectedElements =
        xDocument.XPathSelectElements(
                "/meadinkent/record/comp_div | /meadinkent/record/sty_ret_type");

    Assert.That(selectedElements.Count(), Is.EqualTo(2));
}

Un exemple de filtre C # par sous-nœuds:

[Test]
public void FilterExample()
{
    string xml =
        @"<meadinkent>
            <record>
                <comp_div>MENSWEAR</comp_div> 
                <sty_ret_type>ACCESSORIES</sty_ret_type> 
                <sty_pdt_type>BELTS</sty_pdt_type> 
                <pdt_category>AWESOME_BELTS</pdt_category>
            </record>
          </meadinkent>";

    XDocument xDocument = XDocument.Parse(xml);
    IEnumerable<XElement> selectedElements =
        xDocument.XPathSelectElements(
       "/meadinkent/record[comp_div='MENSWEAR' and sty_ret_type='ACCESSORIES']");

    Assert.That(selectedElements.Count(), Is.EqualTo(1));
    Assert.That(selectedElements.First().Name.LocalName, Is.EqualTo("record"));
}
43
Elisha

Il vous suffit d'avoir la liste de conditions anded à l'intérieur de la [ ] sélecteur pour record:

/meadinkent/record[compdiv[.='MENSWEAR'] and sty_ret_type[.='ACCESSORIES']]

Lit comme: sous un nœud de niveau supérieur meadinkent, un nœud record, ayant un enfant compdiv (avec la valeur MENSWEAR) et = un enfant sty_ret_rype (avec la valeur ACCESSORIES).

7
AakashM

ou vous pouvez utiliser linq to XML et le faire comme ceci:

var match = XElement.Parse(xmlString);

var matches = from xml in xmlDocument.Elements()
              where xml.Element("comp_div").Value == "MENSWEAR"
              && xml.Element("sty_ret_type").Value == "ACCESSORIES"
              && xml.Element("sty_pdt_type").Value == "BELTS"
              && xml.Element("pdt_category").Value == "AWESOME_BELTS"
              select xml;
1
Stéphane