Linq-to-XML XElement.Remove () lässt unerwünschte Leerzeichen zurück

9

Ich habe ein XDocument, das ich aus einem Byte-Array (über tcp / ip) erstellt habe.

Ich suche dann nach bestimmten XML-Knoten (XElements) und nach dem Abrufen des Wertes "pop" es von XDocument durch den Aufruf von XElement.Remove (). Nachdem mein gesamtes Parsen beendet ist, möchte ich in der Lage sein, das XML zu protokollieren, das ich nicht analysiert habe (das verbleibende XML im XDocument). Das Problem besteht darin, dass beim Aufruf von XElement.Remove () zusätzliche Leerzeichen vorhanden sind. Ich möchte die beste Möglichkeit kennen, diesen zusätzlichen Leerraum zu entfernen, während der Rest des Formats in dem verbleibenden XML beibehalten wird.

Beispiel / Beispielcode

Wenn ich das folgende xml über den Sockel bekomme:

%Vor%

Und ich verwende den folgenden Code, um dieses XML zu analysieren und eine Anzahl der XElements zu entfernen:

%Vor%

Die resultierende XML-Zeichenfolge, die an die LogUnparsedXML-Nachricht gesendet wird, lautet dann wie folgt:

%Vor%

In diesem erfundenen Beispiel mag es nicht so schlimm erscheinen, aber in meiner tatsächlichen Anwendung sieht das übriggebliebene XML ziemlich schlampig aus. Ich habe versucht, die XDocument.ToString-Überladung zu verwenden, die ein SaveOptions-Enum vergeblich nimmt. Ich habe auch versucht, xDoc.Save aufzurufen, um mit der SaveOptions-Enumeration in eine Datei zu speichern. Ich habe versucht, mit ein paar verschiedenen Linq-Abfragen zu experimentieren, die XElement.Nodes().OfType<XText>() verwendeten, um zu versuchen, das Leerzeichen zu entfernen, aber oft nahm ich das Leerzeichen, das ich behalten möchte, zusammen mit dem Leerzeichen, das ich loswerden möchte. p>

Vielen Dank im Voraus für Ihre Unterstützung.

Joe

    
Joe DePung 27.07.2011, 21:05
quelle

1 Antwort

3

Es ist nicht leicht, auf tragbare Weise zu antworten, weil die Lösung stark davon abhängt, wie XDocument.Load() Leerzeichen-Textknoten generiert (und es gibt mehrere Implementierungen von LINQ to XML, die bei diesem subtilen Detail nicht übereinstimmen).

>

Es sieht so aus, als ob Sie niemals das letzte Kind ( <description> ) aus den <book> -Elementen entfernen. Wenn das tatsächlich der Fall ist, müssen wir uns nicht um das Einrücken des schließenden Tags des übergeordneten Elements kümmern, und wir können das Element und alle folgenden Textknoten einfach entfernen, bis wir ein anderes Element erreichen. TakeWhile () erledigt die Aufgabe.

BEARBEITEN: Nun, es sieht so aus, als müssten Sie das letzte Kind entfernen. Daher werden die Dinge komplizierter. Der folgende Code implementiert den folgenden Algorithmus:

  
  • Wenn das Element nicht das letzte Element des übergeordneten Elements ist:   
    • Entfernen Sie alle folgenden Textknoten, bis wir das nächste Element erreichen.
    •   
  •   
  • Ansonsten:   
    • Entfernen Sie alle folgenden Textknoten, bis wir einen gefunden haben, der eine neue Zeile enthält,
    •   
    • Wenn dieser Knoten nur eine neue Zeile enthält:   
      • Entferne diesen Knoten.
      •   
    •   
    • Ansonsten:   
      • Erstellen Sie einen neuen Knoten, der nur den nach dem Zeilenumbruch gefundenen Leerzeichen enthält,
      •   
      • Fügen Sie diesen Knoten nach dem ursprünglichen Knoten
      • ein   
      • Entfernen Sie den ursprünglichen Knoten.
      •   
    •   
  •   
  • Entfernen Sie das Element selbst.
  •   

Der resultierende Code lautet:

%Vor%

Von dort können Sie tun:

%Vor%

Obwohl ich vorschlagen würde, dass Sie das Obige durch etwas wie eine Schleife ersetzen, die von einem Array oder einem params Methodenaufruf gespeist wird, um Code-Redundanz zu vermeiden.

    
Frédéric Hamidi 27.07.2011, 21:46
quelle

Tags und Links