2016-04-06 3 views
1

На этой странице MSDN показано, как использовать Linq-to-XML для поиска узлов XML, содержащих определенный дочерний узел. К сожалению, у меня есть противоположная проблема: у меня большой список, и некоторые из этих узлов: отсутствует определенный дочерний узел, который должен быть там. Есть ли хороший способ их найти?Как найти узел XML, в котором отсутствует определенный дочерний узел?

Например:

<Objects> 
    <Object> 
    <ID>1</ID> 
    <A>1</A> 
    <B>1</B> 
    <C>1</C> 
    </Object> 
    <Object> 
    <ID>2</ID> 
    <A>2</A> 
    <B>2</B> 
    <C>2</C> 
    </Object> 
    <Object> 
    <ID>3</ID> 
    <A>3</A> 
    <C>3</C> 
    </Object> 
    <Object> 
    <ID>4</ID> 
    <A>4</A> 
    <B/> 
    <C>4</C> 
    </Object> 
</Objects> 

Как бы настроить код, чтобы найти все <Object> элементы с отсутствующей <B> узла, который будет возвращать # 3, но не # 4?

ответ

1

Это работает, потому что XContainer.Element("elementName") возвращает null если elementName не существует (примечание: я скопировал ваш XML в строку под названием xml, так что вам нужно просто сделать .Descendents на вашем XDocument):

static void Main(string[] args) 
    { 
     var elementsWithoutB = XDocument.Parse(xml) 
           .Descendants("Object") 
           .Where(x => x.Element("B") == null); 

     // Prove it works by printing the elements returned 
     foreach (var element in elementsWithoutB) 
     { 
      Console.WriteLine(element.ToString()); 
     } 

     Console.Read(); 
    } 
1

Вот другой работы вокруг, если вы хотите использовать XPath для этого случая, вы можете использовать приведенный ниже подход также:

static void Main(string[] args) 
     { 
      XElement objects = XElement.Parse(@"<Objects> 
                <Object> 
                <ID>1</ID> 
                <A>1</A> 
                <B>1</B> 
                <C>1</C> 
                </Object> 
                <Object> 
                <ID>2</ID> 
                <A>2</A> 
                <B>2</B> 
                <C>2</C> 
                </Object> 
                <Object> 
                <ID>3</ID> 
                <A>3</A> 
                <C>3</C> 
                </Object> 
                <Object> 
                <ID>4</ID> 
                <A>4</A> 
                <B/> 
                <C>4</C> 
                </Object> 
               </Objects>"); 

      string xpath_string = "//Object[count(B) = 0]"; //you can change the name of the element anytime, 
                  //even in the run-time also... just make sure 
                  //to add `System.Xml.XPath` to utilize the XPath... 

      IEnumerable<XElement> query_for_objects = objects.XPathSelectElements(xpath_string); 

      foreach (XElement ele in query_for_objects) 
      { 
       Console.WriteLine(ele.ToString()); 
      } 
      Console.ReadKey(); 

Что такое п лед, используя XPath для этого случая, вы можете использовать индивидуальный запрос даже во время выполнения, не изменяя свой код вообще!

Смежные вопросы