Autor Beitrag
alexpj
Hält's aus hier
Beiträge: 12



BeitragVerfasst: So 17.01.21 14:07 
hallo!

aufgrund meinder bescheidenen Hobbyprogrammierkenntnisse verzweifel ich an dem Verarbeiten einer einer (Eport) XML Datei aus einem Aufmaßprogramm.
Es gibt darin ein Konten
ausblenden XML-Daten
1:
2:
<Children>
    <ProjectChild xsi:type="Group">

der wiederum identisch benannte Childs hat
ausblenden XML-Daten
1:
2:
 <children>
        <ProjectChild xsi:type="Position">


Versuche ich das ganz normal in ein DataSet einzulesen gibt es aufgrund der doppelten Namen eine Fehlermeldung.

Frage 1:
Wie kann ich die xsi:type="..." berücksichtigen?
Frage 2:
Bei einem automatisierten Umbenennen ist es im am identischen </ProjectChild> gescheitert.
Gäbe es eine Möglichkeit die Knoten umzubennen?

Das Ziel der Maßnahme soll ein zeilenweises Einlesen in ein einzelnes DatagridView sein...

Danke & Gruss,
Alex


hier als ganzes:
ausblenden volle Höhe XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
<Project xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Children>
    <ProjectChild xsi:type="Group">
      <Number>1</Number>
      <Name>Farbige Wände</Name>
      <children>
        <ProjectChild xsi:type="Position">
          <Number>1</Number>
          <Name>violettblau RAL 5000 RH=300cm</Name>
          <CalculationItems>
            <CalculationItem xsi:type="PointCalculationItem">
              <Name>Wand RAL5000</Name>
              <Comment />
              <Count>1</Count>
              <Area>63.7981846861768</Area>
              <AreaFormula>plo * h = (4,94+1+4,94+9,07+0,11) * 3,18</AreaFormula>
              <Length>20.0623222283575</Length>
              <LengthFormula>plo = (4,94+1+4,94+9,07+0,11)</LengthFormula>
              <Volume>0</Volume>
              <VolumeFormula>plo * h * w = (4,94+1+4,94+9,07+0,11) * 3,18 * 0</VolumeFormula>
              <Sign>1</Sign>
            </CalculationItem>
            <CalculationItem xsi:type="PointCalculationItem">
              <Name>Wand RAL5000</Name>
              <Comment />
              <Count>1</Count>
              <Area>63.7981846861768</Area>
              <AreaFormula>plo * h = (4,94+1+4,94+9,07+0,11) * 3,18</AreaFormula>
              <Length>20.0623222283575</Length>
              <LengthFormula>plo = (4,94+1+4,94+9,07+0,11)</LengthFormula>
              <Volume>0</Volume>
              <VolumeFormula>plo * h * w = (4,94+1+4,94+9,07+0,11) * 3,18 * 0</VolumeFormula>
              <Sign>1</Sign>
            </CalculationItem>
          </CalculationItem>


Gruppe als auch Position gibt es ggf. mehrfach
Einloggen, um Attachments anzusehen!
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4366
Erhaltene Danke: 940

Win10
C#, C++ (VS 2015/17/19)
BeitragVerfasst: So 17.01.21 15:19 
Mit welcher Komponente liest du denn die XML-Daten aus?
alexpj Threadstarter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: So 17.01.21 16:33 
ausblenden C#-Quelltext
1:
2:
3:
4:
XmlReader xmlFile;
xmlFile = XmlReader.Create(filename, new XmlReaderSettings());
DataSet ds1 = new DataSet();
ds1.ReadXml(xmlFile);

erzeugt eine unbehandelte Ausnahme:
System.ArgumentException: "Die Tabelle (ProjectChild) kann in geschachtelten Beziehungen nicht sich selbst untergeordnet sein."

so auch:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
XmlDocument doc = new XmlDocument();
doc.Load(filename);
XmlNodeReader reader = new XmlNodeReader(doc);
DataSet ds = new DataSet();
ds.ReadXml(reader);
reader.Close();

System.ArgumentException: "Die Tabelle (ProjectChild) kann in geschachtelten Beziehungen nicht sich selbst untergeordnet sein."
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4366
Erhaltene Danke: 940

Win10
C#, C++ (VS 2015/17/19)
BeitragVerfasst: Mo 18.01.21 09:01 
Wie wurde die XML-Datei denn erzeugt (auch mittels DataSet.WriteXml)?

Ansonsten wäre XML-Serialisierung hier auch empfehlenswert, s. als Einstieg Mit XmlSerializer Objekte als XML speichern und laden.
Mit dem bei Visual Studio mitgeliefertem Kommandozeilentool XML Schema Definition-Tool (Xsd.exe) kannst du dir auch zuerst eine XML Schema-Datei (".xsd") aus der XML-Datei erzeugen und daraus dann mit der Option "/c" C#-Code (Klassen für die XML-Objekte) erzeugen lassen.
Falls dann noch Probleme bzgl. "xsi:type" bestehen, hilft evtl. Linq-ing XML Specific Types (and how to overcome a .Net bug) (bes. der letzte Absatz).

Evtl. hilft aber auch die Option "/d", welche dir eine von DataSet abgeleitete Klasse erstellt, welche du dann bei deinem bisherigen Code benutzen könntest.

PS: Das Erstellen eines Schemas geht auch direkt von VS aus: Vorgehensweise: Erstellen eines XML-Schemas aus einem XML-Dokument

PPS: Ein umfangreicheres Tool gibt es als VS-AddIn: xsd2Code++

Und bitte Crossposts (s. Richtlinien "3.10 Crosspostings") hier immer angeben: MyCSharp.de - xml verarbeiten mit doppelten Knotennamen, die nur xsi:type Unterschiede haben
alexpj Threadstarter
Hält's aus hier
Beiträge: 12



BeitragVerfasst: Di 26.01.21 19:25 
Danke für die Anregungen. Ich habe es ganz simpel über eine xslt Datei geregelt, welches die Knoten eindeutig umbenennt und für mich unnötiges auch gleich herausnimmt:

Zeile 5-9 übernimmer erst einmal alles zum Bearbeiten
Zeile 11-15 nimmt die xsi:Type als Namensbestanteil in den Knotennamen
Zeile 17-21 löscht die Nodes
Zeile 23-40 Löscht die alles was ich nicht benötige

ausblenden volle Höhe XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="xml" indent="yes"/>
  
  <xsl:template match="@*|node()">
     <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
     </xsl:copy>
    </xsl:template>
  
    <xsl:template match="*[@xsi:type]">
     <xsl:element name="{name()}{@xsi:type}">
      <xsl:apply-templates/>
     </xsl:element>
    </xsl:template>
  
  <xsl:template match="CalculationItem">
    <CalculationItem>
        <xsl:apply-templates/>
    </CalculationItem>
</xsl:template>
    
   <xsl:template match="Column[@SourceColumn='points']|points" />
  <xsl:template match="Column[@SourceColumn='Sources']|Sources" />
  <xsl:template match="Column[@SourceColumn='CalculationSource']|CalculationSource" />
  <xsl:template match="Column[@SourceColumn='Sign']|Sign" />
  <xsl:template match="Column[@SourceColumn='VolumeFormula']|VolumeFormula" />
  <xsl:template match="Column[@SourceColumn='Volume']|Volume" />
  <xsl:template match="Column[@SourceColumn='Variables']|Variables" />
  
  <xsl:template match="Children">
  <xsl:apply-templates/>
    </xsl:template>
  <xsl:template match="children">
  <xsl:apply-templates/>
    </xsl:template>
  
  <xsl:template match="CalculationItems">
  <xsl:apply-templates/>
    </xsl:template>
    
</xsl:stylesheet>