2016-06-14 7 views
5

Ich verwende einen Code aus Code Project, um eine XML-Datei in mehrere Dateien aufzuteilen. Es arbeitet in diesem unten Fall fein: „Anmeldungen“ sind der übergeordnete Knoten und wenn Spaltung unter „Registrierung“ ist.net C# XML-Datei splitten

<Registrations> 
<Registration xmlns:i="..............."> 
    <RegistrationID>108260</RegistrationID> 
................... 
.................. 
</Registration> 
<Registration xmlns:i="..............."> 
    <RegistrationID>108260</RegistrationID> 
    ................... 
    .................. 
</Registration> 
<Registration xmlns:i="..............."> 
    <RegistrationID>108260</RegistrationID> 
    ................... 
    .................. 
</Registration> 

Aber der Code funktioniert nicht, wenn XML-Datei in diesem Format ist: " RegistrationOpenData“ist der Wurzelknoten, dann gibt es einen weiteren Knoten‚Anmeldungen‘und Split hat unter gemacht werden‚Registrierung‘

<RegistrationOpenData xmlns:i="............" xmlns=""> 
<Description>......</Description> 
<InformationURL>..........</InformationURL> 
<SourceAgency>...............</SourceAgency> 
<SourceSystem>...........</SourceSystem> 
<StartDate>................</StartDate> 
<EndDate i:nil="true" /> 
<Registrations> 
<Registration xmlns:i="..............."> 
    <RegistrationID>108260</RegistrationID> 
................... 
.................. 
</Registration> 
<Registration xmlns:i="..............."> 
    <RegistrationID>108260</RegistrationID> 
................... 
.................. 
</Registration> 
<Registration xmlns:i="..............."> 
    <RegistrationID>108260</RegistrationID> 
................... 
.................. 
</Registration> 
</Registrations> 
</RegistrationOpenData> 

der Code, den ich benutze ist wie folgt:

private void buttonSPLIT_Click(object sender, EventArgs e) 
{ 
    string sourceFile = @"D:\sample.xml"; 
    string rootElement = "RegistrationOpenData"; 
    string descElement = "Registration"; 
    int take = 1; 
    string destFilePrefix = "RegistrationsPart"; 
    string destPath = @"D:\PART\"; 

    SplitXmlFile(sourceFile, rootElement, descElement, take, 
     destFilePrefix, destPath); 

} 

private static void SplitXmlFile(string sourceFile 
        , string rootElement 
        , string descendantElement 
        , int takeElements 
        , string destFilePrefix 
        , string destPath) 
{   
    XElement xml = XElement.Load(sourceFile); 
    // Child elements from source file to split by. 
    var childNodes = xml.Descendants(descendantElement); 

    // This is the total number of elements to be sliced up into 
    // separate files. 
    int cnt = childNodes.Count(); 

    var skip = 0; 
    var take = takeElements; 
    var fileno = 0; 

    // Split elements into chunks and save to disk. 
    while (skip < cnt) 
    { 
     // Extract portion of the xml elements. 
     var c1 = childNodes.Skip(skip) 
         .Take(take); 

     // Setup number of elements to skip on next iteration. 
     skip += take; 
     // File sequence no for split file. 
     fileno += 1; 
     // Filename for split file. 
     var filename = String.Format(destFilePrefix + "_{0}.xml", fileno); 
     // Create a partial xml document. 
     XElement frag = new XElement(rootElement, c1); 
     // Save to disk. 
     frag.Save(destPath + filename); 
    } 
} 
+0

'XElement.Descendants' ist in seinen Ergebnissen rekursiv. Ich denke, Sie könnten tatsächlich nach 'XElement.Elements' suchen – pquest

+0

Ich versuchte mit var childNodes = xml.Elements (" Registrierung "); statt var childNodes = xml.Descendants (descendantElement); aber es funktioniert immer noch nicht. Gib keine Ergebnisse. – Karishma

+0

Können Sie anzeigen, welche Ausgabe Sie erwarten? –

Antwort

1

Ich habe gerade Ihren Code in VS 2015 getestet und es scheint zu funktionieren. Es generiert 3 XML-Dateien mit folgendem Inhalt:

<?xml version="1.0" encoding="utf-8"?> 
<RegistrationOpenData> 
    <Registration> 
    <RegistrationID>108260</RegistrationID> 
    </Registration> 
</RegistrationOpenData> 

Ist es das, was Sie erwarten? Können Sie weitere Einzelheiten zu Ihrem Problem angeben?

+0

Ich verwende VS 2012. Das erste Format, das ich in dieser Frage angegeben habe, ist die erwartete Ausgabe. Wenn aus der XML-Datei der übergeordnete Knoten "RegistrationOpenData" entfernt wird, funktioniert der Code einwandfrei und die Datei wird aufgeteilt. Wenn jedoch "RegistrationOpenData" und "Registrations" vorhanden sind, passiert nichts. Keine Fehler, kein Split. – Karishma

0

als eine schnelle Lösung (i nehme an, Sie wollen nicht, Änderungen in Ihrem Codeproject Skript machen) Sie diese Zeile hinzufügen:

private static void SplitXmlFile(string sourceFile 
        , string rootElement 
        , string descendantElement 
        , int takeElements 
        , string destFilePrefix 
        , string destPath) 
{ 
    XElement xml = XElement.Load(sourceFile); 
    XNamespace ns = "http://services.hpd.gov"; // This line must be added. 
    xml = xml.Element(ns + rootElement); // rootElement must be "Registrations". And also this line must be added. 
    // Child elements from source file to split by. 
    var childNodes = xml.Descendants(ns + descendantElement); 
..... 
..... 

hier arbeitet Beispiel: https://dotnetfiddle.net/6sOOdH

+0

Ich habe diese Modifikation versucht, aber immer noch nicht funktioniert. Ich benutze VS2012. Ich hoffe, das ist nicht der Fall. – Karishma

+0

In meinem Fall gibt der Code childNodes.Count() 0 zurück, daher tritt er nicht einmal in die while-Schleife ein. – Karishma

+0

Hallo, ich habe es in Geige versucht und es ist zu loop.https: //dotnetfiddle.net/6sOOdH –