2010-04-08 10 views
25

tengo un documento XML que se ve algo como esto:en múltiples criterios con 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> 

Quiero useXPath para seleccionar los nodos que coinciden con los cuatro elementos y estoy teniendo problemas para conseguir el derecho de sintaxis booleana . Estoy intentando que esto coincide con los dos primeros simplemente como una prueba:

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

¿Qué está fallando, diciendo no se devuelven los nodos. Obviamente estoy siendo muy estúpido, ¿qué estoy haciendo mal?

Saludos, Matt

Respuesta

42

Unión
Con el fin de obtener los dos nodos es necesario utilizar operador de unión - |

Por ejemplo, la siguiente consulta devolverá ambos tipos de nodos - comp_div y sty_ret_type:

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

Fi filtro de sub-nodos valora
Para filtrar nodo basado en sus sub-nodos valores se han de fijar todas las condiciones en las mismas soportes [nodeA='value1' and nodeB='value2']

Por ejemplo, la siguiente consulta devolverá los nodos de registro cuyo nodos sub coincidir con el filtro:

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

AC ejemplo # unión:

[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# filtro por subnodos ejemplo:

[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

Lo sentimos, no he sido claro. Lo que busco es una referencia al nodo Record que coincide con todos los valores de los elementos en el interior. Entonces, si quiero afirmar que sty_pdt_type es "BELTS" y pdt_category es "AWESOMEBELTS", quiero una referencia a todos los nodos de registro para los cuales esos elementos coinciden con esos valores. –

+0

@Matt Thrower, entiendo ahora lo que querías decir :) Respuesta actualizada en consecuencia. – Elisha

+0

Impresionante, gracias! –

6

Usted sólo tiene que tener la lista and ed de las condiciones dentro el selector [ ] para record:

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

dice así: bajo un nodo de nivel superior meadinkent, un nodo record, tener un hijo compdiv (con valor MENSWEAR) y un hijo sty_ret_rype (con valor ACCESSORIES).

1

o puede utilizar LINQ para XML y hacerlo de esta manera:

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; 
Cuestiones relacionadas