Выберите на нескольких критериях с 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>

Я хочу к useXPath выбрать узлы, которые соответствуют всем четырем элементам, и я испытываю затруднения при разбирании в булевом синтаксисе. Я пробую это для соответствия первым двум так же, как тесту:

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

Который перестал работать, говоря, что никакие узлы не возвращаются. Очевидно, я очень глуп - что я делаю неправильно?

С наилучшими пожеланиями, матовый

27
задан Bob Tway 8 April 2010 в 10:49
поделиться

3 ответа

Union
Чтобы получить оба узла, вам необходимо использовать оператор объединения - |

Например, следующий запрос вернет оба типа узлов - comp_div и sty_ret_type :

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

Фильтр по значениям подузлов
Чтобы отфильтровать узел на основе значений его подузлов, вам необходимо разместить все условия в тех же скобках [nodeA = 'значение1' и nodeB = 'значение2']

Например, следующий запрос вернет узлы записей, подузлы которых соответствуют фильтру:

/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"));
}
43
ответ дан 28 November 2019 в 05:06
поделиться

или вы можете использовать linq to 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;
1
ответ дан 28 November 2019 в 05:06
поделиться

Вам просто нужно иметь и - список условий внутри селектора [] для записи :

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

Читается как: под верхним уровнем узел meadinkent , узел записи , имеющий дочерний compdiv (со значением MENSWEAR ) и дочерний sty_ret_rype (со значением АКСЕССУАРЫ ).

7
ответ дан 28 November 2019 в 05:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: