2009-11-03 90 views
1

我正在做一些使用xlinq的變換,其中一些變換可能導致在文檔中留下空元素。使用xlinq刪除所有空元素

一旦我完成了所有這些轉換,我如何查詢所有空元素的xdocument?

換句話說;如果我刪除所有<a>標籤,而這些標籤恰好是<li>標籤中的唯一元素,那麼如何刪除空的<li>

前:

XDocument.Parse(@"<body> 
    <ul><li><a href="#">Joy</a></li></ul> 
    <p>Hi.</p> 
</body>").Descendants("a").Remove(); 

後:

<body> 
    <ul><li/></ul> 
    <p>Hi.</p> 
</body> 

我寧願:

<body> 
    <p>Hi.</p> 
</body> 

回答

10

檢查元素doesn't have attributedoesn't have elements是否不夠。你需要檢查一個元素是否真的是空的(絕對沒有內容)。 XElement有一個屬性,實際上可以幫助你做到這一點 - XElement.IsEmpty

var document = XDocument.Parse(@"<body><ul><li><a href='#'>Joy</a></li></ul><p>Hi.</p></body>"); 
document.Descendants("a").Remove(); 

var emptyElements = from element in document.Descendants() 
        where element.IsEmpty 
        select element; 

while (emptyElements.Any()) 
    emptyElements.Remove(); 
0

我能想出的最好的是...

var emptyElements = 
    from element in document.Descendants() 
    where !element.Attributes().Any() && !element.Elements().Any() 
    select element; 


while(emptyElements.Any()) 
    emptyElements.Remove(); 

然後我意識到這是一個壞主意,它消除了太多,但我沒有花時間弄清楚爲什麼。

1

給予的XmlNodeList這一功能的嘗試此代碼 希望這將工作從XML文件

public static XmlNode RemoveNullElement(XmlNodeList xmlNodeList) 
    { 
     if (xmlNodeList.Count > 0) 
     { 
      foreach (XmlNode xmlnode in xmlNodeList) 
      { 
       RemoveNullChildAndAttibute(xmlnode); 
       return xmlnode; 
      } 
     } 

     return null; 
    } 


    public static void RemoveNullChildAndAttibute(XmlNode xmlNode) 
    { 
     if (xmlNode.HasChildNodes) 
     { 
      for (int xmlNodeCount = xmlNode.ChildNodes.Count - 1; xmlNodeCount >= 0; xmlNodeCount--) 
      { 
       RemoveNullChildAndAttibute(xmlNode.ChildNodes[xmlNodeCount]); 
      } 
     } 
     else if (xmlNode.Attributes.Count == 0) 
     { 
      if (xmlNode.ParentNode != null) 
      { 
       xmlNode.ParentNode.RemoveChild(xmlNode); 
      } 
     } 
    } 
0

這裏接受的答案是不完全正確刪除所有空的元素和屬性。具體來說,它只會刪除<foo />形式的元素,並會留下像<foo></foo>這樣的元素。

因此,這裏是一個完整的解決方案:

public static void RemoveEmptyDescendants(this XNode node) 
{ 
    var empty = from e in node.Descendants() 
       where !e.Nodes().Any() && !e.Attributes().Any() 
       select e; 

    while (empty.Any()) 
    { 
     empty.Remove(); 
    } 
} 
0

檢查都爲IsEmpty和HasAttributes是更有幫助。

 var emptyElements = document.Descendants() 
          .Where(element => element.IsEmpty 
              && !element.HasAttributes); 
     while (emptyElements.Any()) 
     { 
      emptyElements.Remove(); 
     } 

對於只有屬性的元素,IsEmpty將返回true。例如:

 <Participant xsi:nil="true"/>