2011-01-16 11 views
2

Ich bin ein Anfänger in der Verwendung von LINQ. Ich habe ein XML-Daten mit dem Format unterWie kann ich XML-Abschnitte filtern und als Datei speichern

<Root> 
    <Global> 
    </Global> 
    <local> 
     <element name="A"> 
      <subelement name="A"> 
       <element name="A1"> 
        <subelement name="A1"> 
         <Property> 
         </Property> 
        </subelement> 
       </element> 
       <element name="B"> 
        <Property> 
        </Property> 
       </element> 
      </subelement> 
      <subelement name="B"> 
       <element name="A"> 
        <Property> 
        </Property> 
       </element> 
       <element name="B"> 
        <Property> 
        </Property> 
       </element> 
      </subelement> 
     </element> 
    </local> 
</Root> 

ich jeden Abschnitt des Property Elements gespeichert werden soll in seine eigene XML-Datei wie unten während der Hierarchiestruktur intakt

<Root> 
    <Global> 
    </Global> 
    <local> 
     <element name="A"> 
      <subelement name="A"> 
       <element name="A1"> 
        <subelement name="A1"> 
         <Property> 
         </Property> 
       </subelement> 
       </element> 
      </subelement> 
     </element> 
    </local> 
</Root> 

und

<Root> 
    <Global> 
    </Global> 
    <local> 
     <element name="A"> 
      <subelement name="A"> 
       <element name="B"> 
        <Property> 
        </Property> 
       </element> 
      </subelement> 
     </element> 
    </local> 
</Root> 

und so weiter für alle Eigenschaft Elemente. Jedes Element kann ein Kind Subelement hat und jedes Subelement können habe Element Kind

Können Sie eine Lösung geben, wie jeden Abschnitt von Property Elemente als eine neue XML-Datei mit dem aktuellen speichern Hierarchiestruktur intakt. Ich habe versucht, den Vorfahr() -Methode der XElement-Klasse

XDocument xml = XDocument.Load(filename); 
XDocument convertedQuery = new XDocument(
     new XElement(xml.Root.Name, from x in xml.Descendants("local") 
            select x.Ancestors()) 
     ); 

aber es kehrt andere Property Elemente als auch, wie unten

<Root> 
<Global></Global> 
<local> 
    <element name="A"> 
    <subelement name="A"> 
     <element name="A1"> 
     <subelement name="A1"> 
      <Property></Property> 
     </subelement> 
     </element> 
     <element name="B"> 
     <Property></Property> 
     </element> 
    </subelement> 
    <subelement name="B"> 
     <element name="A"> 
     <Property></Property> 
     </element> 
     <element name="B"> 
     <Property></Property> 
     </element> 
    </subelement> 
    </element> 
</local> 

Jede Hilfe wäre viel geschätzt. Danke

Antwort

2

Hier ist ein C# Beispiel, das tun sollte, was Sie wollen oder Ihnen zumindest eine Idee geben, wie Sie das angehen können. Die Probe für den Test schreibt einfach jede erstellt XDocument-Console.Out aber natürlich könnten Sie das in eine Datei auf der Festplatte zu speichern, ändern:

static void Main(string[] args) 
{ 
    XDocument doc = XDocument.Load(@"..\..\XMLFile1.xml"); 
    foreach (XElement prop in doc.Descendants("Property")) 
    { 
     XDocument result = new XDocument(
      new XElement(doc.Root.Name, doc.Root.Attributes(), 
       doc.Root.Elements("Global"), 
       CopySubtree(prop.Ancestors("local").First(), prop))); 
     result.Save(Console.Out); 
     Console.WriteLine(); 
    } 
} 
static XElement CopySubtree(XElement ancestor, XElement descendant) 
{ 
    if (ancestor == descendant) 
    { 
     return descendant; 
    } 
    else 
    { 
     return 
      new XElement(
       ancestor.Name, 
       ancestor.Attributes(), 
       CopySubtree(
        ancestor 
        .Elements() 
        .First(e => e.DescendantsAndSelf().Any(d => d == descendant)), 
        descendant)); 
    } 
} 

[Bearbeiten] Für die neue Anforderung nicht nur das Objekt Vorfahr zu kopieren, sondern auch seine Geschwister können Sie oben Methode wie folgt anpassen:

static XElement CopySubtree(XElement ancestor, XElement descendant) 
{ 
    if (ancestor == descendant.Parent) 
    { 
     return ancestor; 
    } 
    else 
    { 
     return 
      new XElement(
       ancestor.Name, 
       ancestor.Attributes(), 
       CopySubtree(
        ancestor 
        .Elements() 
        .First(e => e.DescendantsAndSelf().Any(d => d == descendant)), 
        descendant)); 
    } 
} 
+0

Vielen Dank. Es funktioniert perfekt – user577387

Verwandte Themen