使用XPath选择多个条件

时间:2010-04-08 10:49:21

标签: xpath

我有一个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>
<medinkent>

我想使用XPath来选择与所有四个元素匹配的节点,并且我无法正确获取布尔语法。我正在尝试将前两个作为测试匹配:

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

哪个失败,说没有返回节点。显然我是非常愚蠢的 - 我做错了什么?

干杯, 马特

3 个答案:

答案 0 :(得分:42)

<强>联盟
为了获得两个节点,您需要使用union运算符 - |

例如,下一个查询将返回两种类型的节点 - comp_divsty_ret_type

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

按子节点值过滤
为了根据子节点值过滤节点,您需要将所有条件放在相同的括号中[nodeA='value1' and nodeB='value2']

例如,下一个查询将返回其子节点与过滤器匹配的记录节点:

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

C#union示例:

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

按子节点示例的C#过滤器:

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

答案 1 :(得分:7)

您只需要在and的{​​{1}}选择器中 } [ ]条件列表

record

读取为:在顶级/meadinkent/record[compdiv[.='MENSWEAR'] and sty_ret_type[.='ACCESSORIES']] 节点下,meadinkent节点,有一个小孩record(值compdiv孩子MENSWEAR(价值为sty_ret_rype)。

答案 2 :(得分:1)

或者您可以将linq用于XML并按照以下方式执行:

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;