2016-04-06 10 views
1

Diese MSDN-Seite zeigt, wie Linq-to-XML verwendet wird, um XML-Knoten zu finden, die einen bestimmten untergeordneten Knoten enthalten. Leider habe ich das umgekehrte Problem: Ich habe eine große Liste und einige dieser Knoten sind fehlt ein bestimmter Kind-Knoten, der da sein sollte. Gibt es einen guten Weg, sie zu finden?Wie finde ich einen XML-Knoten, dem ein bestimmter untergeordneter Knoten fehlt?

Zum Beispiel:

<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> 

Wie würde ich einrichten Code alle <Object> Elemente mit einem fehlenden <B> Knoten zu finden, die 3 # zurückkehren würde, aber nicht 4 #?

Antwort

1

Das funktioniert, weil XContainer.Element("elementName") kehrt null wenn elementName existiert nicht (Anmerkung: Ich habe Ihr XML in einen String kopiert xml genannt, so dass Sie nur .Descendents tun müssen, um auf Ihrem 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

Hier wenn Sie eine andere Work-around, mag die XPath für diesen Fall nutzen, können Sie den folgenden Ansatz verwenden auch:

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(); 

Was n Eis mit XPath für diesen Fall können Sie eine benutzerdefinierte Abfrage auch zur Laufzeit verwenden, ohne Ihren Code überhaupt zu ändern!