2010-04-08 91 views
25

選擇多個條件我有一個XML文檔,它看起來是這樣的:使用XPath

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

我想useXPath選擇匹配所有四個要素哪些節點,我遇到了麻煩布爾語法正確的。我試圖通過測試來匹配前兩項:

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

這是失敗的,說沒有節點返回。顯然我很愚蠢 - 我做錯了什麼?

乾杯, 馬特

回答

42

聯盟
爲了得到你需要使用union運算的兩個節點 - |

例如,接下來的查詢將返回兩種類型的節點 - comp_divsty_ret_type

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

Fi濾波器的子節點值
爲了過濾節點基於其子節點值,你需要將所有條件相同的括號[nodeA='value1' and nodeB='value2']

例如,一個查詢將返回記錄節點,其子節點匹配濾波器:

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

AC#工會例如:

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

AC由子節點示例#濾波器:

[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

對不起,我沒有說清楚。我所追求的是對Record節點的引用,它與內部的所有元素值匹配。所以,如果我想斷言sty_pdt_type是「BELTS」,而pdt_category是「AWESOMEBELTS」,那麼我想要引用所有這些元素匹配這些值的記錄節點。 – 2010-04-08 11:02:11

+0

@Matt Thrower,我現在明白你的意思了:)相應地更新了答案。 – Elisha 2010-04-08 11:10:08

+0

太棒了,謝謝! – 2010-04-08 11:12:19

6

你只需要具備的條件and編輯列表[ ]選擇了record

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

讀作:下一個頂級meadinkent節點,record節點,有個孩子compdiv(值MENSWEAR小孩sty_ret_rype(值爲ACCESSORIES)。

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;