Select on multiple criteria with XPath

后端 未结 3 1518
时光取名叫无心
时光取名叫无心 2020-12-17 08:46

I have an XML document which looks something like this:


 
  MENSWEAR 
  

        
相关标签:
3条回答
  • 2020-12-17 09:02

    You just need to have the anded list of conditions inside the [ ] selector for record:

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

    Reads as: under a top level meadinkent node, a record node, having a child compdiv (with value MENSWEAR) and a child sty_ret_rype (with value ACCESSORIES).

    0 讨论(0)
  • 2020-12-17 09:04

    Union
    In order to get both nodes you need to use union operator - |

    For example, the next query will return both type of nodes - comp_div and sty_ret_type:

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

    Filter by sub-nodes values
    In order to filter node based on its sub-nodes values you need to place all conditions in same brackets [nodeA='value1' and nodeB='value2']

    For example, the next query will return record nodes whose sub nodes match the filter:

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

    A C# union example:

    [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));
    }
    

    A C# filter by sub-nodes example:

    [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"));
    }
    
    0 讨论(0)
  • 2020-12-17 09:08

    or you could use linq to XML and do it like this :

    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;
    
    0 讨论(0)
提交回复
热议问题