C# Seltsames Verhalten mit XML

Black_Panter

Ensign
Registriert
Mai 2006
Beiträge
197
Moin moin,

ich habe ein XML-Dokument, welches ich durchlaufen will.
Zur auswertung brauch ich jedoch nur bestimmte Knoten, deren Name mir bekannt ist.

Jetzt angenommen in einem Knoten sind 2 Kind-Knoten, von dem ich aber nur einen brauche (dieser hat wiederum Kind-Knoten) und es sicher ist, das der 2. auch nicht gebraucht wird bekomme ich beim versuch via "node.SelectSingleNode("NodeName").ChildNodes" darauf zuzugreifen die Exception "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.".

Wenn ich jedoch immer mit foreach-Schleifen durchlaufe und auf den Knoten-Namen abfrage funktioniert es wie gewollt.

Ich werd nicht wirklich schlüssig daraus, wieso sich das ganze so verhält.

Viele Grüße
Sören
 
Zeig mal das XML-Dokument und wie du per Code drauf zugreifst.
Empfehlen kann ich dir nur, das du mit Linq-To-Xml arbeitest, super einfach und super intuitiv.
 
xml:
Code:
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:o="urn:schemas-microsoft-com:office:office"
 xmlns:x="urn:schemas-microsoft-com:office:excel"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
 xmlns:html="http://www.w3.org/TR/REC-html40">
 <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
  <Title>Data</Title>
  <Author>Soeren</Author>
  <Created>2011-04-29T13:59:52Z</Created>
  <Version>12.00</Version>
 </DocumentProperties>
 <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
  <WindowHeight>10005</WindowHeight>
  <WindowWidth>10005</WindowWidth>
  <WindowTopX>120</WindowTopX>
  <WindowTopY>135</WindowTopY>
  <ProtectStructure>False</ProtectStructure>
  <ProtectWindows>False</ProtectWindows>
 </ExcelWorkbook>
 <Styles>
  <Style ss:ID="Default" ss:Name="Normal">
   <Alignment ss:Vertical="Bottom"/>
   <Borders/>
   <Font ss:FontName="Arial" x:Family="Swiss" ss:Color="#000000"/>
   <Interior/>
   <NumberFormat/>
   <Protection/>
  </Style>
 </Styles>
 <Worksheet ss:Name="Board">
  <Table ss:ExpandedColumnCount="6" ss:ExpandedRowCount="72" x:FullColumns="1"
   x:FullRows="1" ss:DefaultColumnWidth="60">
   <Column ss:Width="189.75"/>
   <Column ss:Width="156"/>
   <Column ss:Width="42"/>
   <Column ss:Width="234.75"/>
   <Column ss:Width="72"/>
   <Row>
    <Cell><Data ss:Type="String">Component</Data></Cell>
    <Cell><Data ss:Type="String">Article Code</Data></Cell>
    <Cell><Data ss:Type="String">MTBF-24</Data></Cell>
    <Cell><Data ss:Type="String">Remark</Data></Cell>
    <Cell><Data ss:Type="String">Editor</Data></Cell>
    <Cell><Data ss:Type="String">Date</Data></Cell>
   </Row>
   <Row>
    <Cell><Data ss:Type="String">Beschreibung</Data></Cell>
    <Cell><Data ss:Type="String">Article-Code</Data></Cell>
    <Cell><Data ss:Type="String">173052</Data></Cell>
    <Cell><Data ss:Type="String"></Data></Cell>
    <Cell><Data ss:Type="String"></Data></Cell>
    <Cell><Data ss:Type="String">09.12.2010</Data></Cell>
   </Row>
   <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
   <PageSetup>
    <Header x:Margin="0.4921259845"/>
    <Footer x:Margin="0.4921259845"/>
    <PageMargins x:Bottom="0.984251969" x:Left="0.78740157499999996"
     x:Right="0.78740157499999996" x:Top="0.984251969"/>
   </PageSetup>
   <Selected/>
   <Panes>
    <Pane>
     <Number>3</Number>
     <ActiveRow>14</ActiveRow>
    </Pane>
   </Panes>
   <ProtectObjects>False</ProtectObjects>
   <ProtectScenarios>False</ProtectScenarios>
  </WorksheetOptions>
 </Worksheet>
</Workbook>

code:
Code:
            StreamReader reader = new StreamReader(path);
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(input);
            
            XmlElement root = doc.DocumentElement;

            foreach (XmlNode typ in root.ChildNodes)
            {
                if (typ.Name == "Worksheet")
                {
                    bool jump = true; // To jump over the first line
                    
                    foreach (XmlNode node in typ.ChildNodes)
                    {
                        if (node.Name == "Table")
                        {
                            foreach (XmlNode row in node.ChildNodes)
                            {
                                if (row.Name == "Column") continue;
                                if (jump) { jump = false; continue; }

                                string[] sa = new string[7];
                                
                                // 
                                sa[0] = typ.Attributes["ssName"].Value;

                                int count = 0;
                                foreach (XmlNode cell in row.ChildNodes)
                                {
                                    sa[count + 1] = cell.ChildNodes.Item(0).InnerText; // cell.ChildNodes.Item(0) = <Data...
                                    count++;
                                }
                                ls.Add(sa);
                            }
                        }
                    }
                }
            }

So ist momentan meine Lösung.
 
Zuletzt bearbeitet:
Schau dir mal Linq-to-Xml an, damit wirst du mehr Freude haben, und sehr wichtig: Schau dir die Namespaces der Elemente genau an ;) Die brauchst du beim Abfragen.
 
So wie ich das sehe haben aber nur die Attribute Namespaces. Oder Irre ich mich da?
 
Jop das ist richtig. Kann aber sein das du da den Namespace auch benötigst, Xelements und XAttributes sind da immer sehr strikt. Probiers einfach mal.
 
Wenn dir LINQ zu schwierig ist, kannst du auch mit xsd.exe eine zur XML passende Klasse generieren, die du dann mit Serialisierung/Deserialisierung direkt in verwertbare Objekt-Listen wandelst ;)
 
Zurück
Oben