2016-04-06 150 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字符串,所以你需要做的只是在.DescendentsXDocument):

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的冰塊,即使在運行時也可以使用自定義查詢,而無需更改代碼!