Autor Beitrag
Drowe
Hält's aus hier
Beiträge: 9

Win XP, Win 7, Win 2008 Server
C# (VS 2008, VS2010)
BeitragVerfasst: Mi 25.08.10 18:12 
Hallo,
ich habe folgendes Problem gestellt bekommen:

Anhand eines XSD-Schemas soll eine Flat File auf Fehler untersucht werden und falls ein Fehler gefunden wird, soll die Stelle an der der Fehler ist ausgegeben werden.
Nach Möglichkeit soll sowohl das Schema, als auch das Flat File beliebig austauschbar sein.


Sowohl Flat File, als auch Schema können sehr komplex sein (Fehlersuche von Hand hat ca 3 Stunden gedauert).
Das Programm soll diese Arbeit übernehmen.

Bisher habe ich erfolglos versucht mit Hilfe der XML Klassen eine Lösung dafür zu finden.
Die nächsten beiden Ideen sind entweder einen Parser zu benutzen, ich weiß leider nicht ob im .NET Framework bereits einer enthalten ist,
oder aus der XSD eine Klasse zu generieren und irgendwie die restlichen Schema informationen auszulesen.

Fähigkeitentechnisch würde ich mich gerade aus dem Anfängerstadium heraus ansiedeln.

Grüße Drowe
Trashkid2000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: Mi 25.08.10 19:37 
Hallo und willkommen im Forum!

Zuerst stellt sich die Frage, was denn ein Flat File ist.
Ich meine, ein XSD-Schema ist ja dazu da, um eine XML- Datei gegen dieses Schema zu validieren. Dabei können Fehler an dem Aufbau, den Datentypen, Wertebereiche usw. festgestellt werden.

Also stelle mir vor, dass das Flat File, wie Du es nennst, ein normales Textdokument ist, das eigentlich keine Struktur hat. Oder verstehe ich das falsch?

Wenn denn keine Struktur vorhanden ist, so müsste erst einmal eine erstellt werden. Das geht aber auch automatisiert.

Aber wäre gut, wenn Du mal einen Ausschnitt aus Flat File und Schema zeigst.

LG, Marko
Drowe Threadstarter
Hält's aus hier
Beiträge: 9

Win XP, Win 7, Win 2008 Server
C# (VS 2008, VS2010)
BeitragVerfasst: Mi 25.08.10 20:18 
Ein sehr einfaches Schema könnte so aussehen:

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:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns="FlatFileSchema1" targetNamespace="FlatFileSchema1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:annotation>
    <xs:appinfo>
      <schemaEditorExtension:schemaInfo namespaceAlias="b" extensionClass="Microsoft.BizTalk.FlatFileExtension.FlatFileExtension" standardName="Flat File" 
        xmlns:schemaEditorExtension="http://schemas.microsoft.com/BizTalk/2003/SchemaEditorExtensions" />
      <b:schemaInfo standard="Flat File" codepage="65001" default_pad_char=" " pad_char_type="char" count_positions_by_byte="false" parser_optimization="speed" 
        lookahead_depth="3" suppress_empty_nodes="false" generate_empty_nodes="true" allow_early_termination="false" early_terminate_optional_fields="false" 
        allow_message_breakup_of_infix_root="false" compile_parse_tables="false" root_reference="Person" />
    </xs:appinfo>
  </xs:annotation>
  <xs:element name="Person">
    <xs:annotation>
      <xs:appinfo>
        <b:recordInfo structure="delimited" child_delimiter_type="hex" child_delimiter="0xD 0xA" child_order="postfix" 
          sequence_number="1" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" />
      </xs:appinfo>
    </xs:annotation>
    <xs:complexType>
      <xs:sequence maxOccurs="3">
        <xs:annotation>
          <xs:appinfo>
            <groupInfo sequence_number="0" xmlns="http://schemas.microsoft.com/BizTalk/2003" />
          </xs:appinfo>
        </xs:annotation>
        <xs:element name="Name" type="xs:string">
          <xs:annotation>
            <xs:appinfo>
              <b:fieldInfo justification="left" sequence_number="1" />
            </xs:appinfo>
          </xs:annotation>
        </xs:element>
        <xs:element name="Nachname" type="xs:string">
          <xs:annotation>
            <xs:appinfo>
              <b:fieldInfo justification="left" sequence_number="2" />
            </xs:appinfo>
          </xs:annotation>
        </xs:element>
        <xs:element name="Datum">
          <xs:annotation>
            <xs:appinfo>
              <b:recordInfo structure="positional" sequence_number="3" preserve_delimiter_for_empty_data="true" suppress_trailing_delimiters="false" />
            </xs:appinfo>
          </xs:annotation>
          <xs:complexType>
            <xs:attribute name="Day" type="xs:string">
              <xs:annotation>
                <xs:appinfo>
                  <b:fieldInfo justification="left" pos_offset="0" pos_length="2" sequence_number="1" />
                </xs:appinfo>
              </xs:annotation>
            </xs:attribute>
            <xs:attribute name="Month" type="xs:string">
              <xs:annotation>
                <xs:appinfo>
                  <b:fieldInfo justification="left" pos_offset="0" pos_length="2" sequence_number="2" />
                </xs:appinfo>
              </xs:annotation>
            </xs:attribute>
            <xs:attribute name="Year" type="xs:string">
              <xs:annotation>
                <xs:appinfo>
                  <b:fieldInfo justification="left" pos_offset="0" pos_length="4" sequence_number="3" />
                </xs:appinfo>
              </xs:annotation>
            </xs:attribute>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>


Die Flat File ist wie du vermutet hast ein ganz normales Textdokument, das jedoch einen im Schema definierten Aufbau haben muss.

In diesem Fall würde das wie folgt aufgebaut sein:

ausblenden Quelltext
1:
2:
3:
Name
Nachname
25082010


Und darf bis zu drei mal vorkommen.
Das zugehörige XML-File sieht dann so aus:

ausblenden XML-Daten
1:
2:
3:
4:
5:
<Person xmlns="FlatFileSchema1">
  <Name xmlns="">Name</Name
  <Nachname xmlns="">Nachname</Nachname
  <Datum Day="25" Month="08" Year="2010" xmlns="" /> 
  </Person>
Trashkid2000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: Mi 25.08.10 20:29 
Okay, also muss aus dem Flat-File also nur die XML aufgebaut werden, und dann gegen das Schema geprüft werden.
Richtig?

Nun gut, also ertsmal müsstest Du Zeile für Zeile im Flat-File durchgehen, und dann die XML erzeugen.
Wo genau ist denn das Problem? Weisst Du nicht, wie Du anfangen sollst, bzw, wie die XML erzeugt wird?

LG, Marko
Drowe Threadstarter
Hält's aus hier
Beiträge: 9

Win XP, Win 7, Win 2008 Server
C# (VS 2008, VS2010)
BeitragVerfasst: Mi 25.08.10 21:07 
Die Aufgabenstellung ist, dass die FlatFile ohne eine vorherige Umwandlung in XML darauf überprüft wird ob sie korrekt ist, und wenn ein Fehler enthalten ist soll der lokalisiert oder zumindest eingegrenzt werden.

Die Umwandlung in XML wäre auch nicht das Problem, dafür habe ich ein Tool. Und solange alles in der File korrekt war hat das auch keine Schwierigkeiten. Aber in manchen Fällen lässt sich die FlatFile zwar umwandeln und validieren, das Ergebnis ist jedoch aufgrund eines Fehlers in der FlatFile sinnlos und kann nicht weiterverarbeitet werden. Und sich dann durch eine unter Umständen 1000 zeilige Textdatei zu wühlen um einen fehlerhaften Eintrag zu finden ist sehr Zeitaufwendig und nervig.

Lg Daniel
Trashkid2000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: Mi 25.08.10 21:38 
Also, bei diesem einfachen Beispiel wäre das Ganze ja nicht so das Problem. Auch obne Umwandlung in eine XML.
Aber ich denke, das war nur ein Auszug aus dem Ganzen. Ändert sich denn das Schema oft, oder wird darauf Wert gelegt?

Ansonsten ist auch die große Frage, wie denn die Flat-Datei erzeugt wird. Vielleicht kann man da ansetzen.

Marko
Drowe Threadstarter
Hält's aus hier
Beiträge: 9

Win XP, Win 7, Win 2008 Server
C# (VS 2008, VS2010)
BeitragVerfasst: Do 26.08.10 08:41 
Bei diesem Beispiel ist es einfach, aber das ganze soll für beliebige Schemas möglich sein. Da die ja alle die selbe Syntax verwenden muss das auch möglich sein.

Über die Erzeugung der FlatFile habe ich keinerlei Kontrolle, die kommt von aussen, ich weiß auch nicht sicher wie die Erzeugt wird, aber ich bezweifele, dass die einer von Hand eintippt. Die sind unter Umständen recht seltsam Formatiert.

Die für die Formatierung der FlatFile wichtigen Teile des Schemas sehen zum Beispiel so aus:

ausblenden XML-Daten
1:
2:
<b:recordInfo structure="positional" sequence_number="3" preserve_delimiter_for_empty_data="true" 
suppress_trailing_delimiters="false" />


ausblenden XML-Daten
1:
<b:fieldInfo justification="left" pos_offset="0" pos_length="2" sequence_number="1" />					


Wenn das ganze mit Hilfe eines Parsers gelöst werden soll muss der Parser diese Informationen interpretieren können.

Daniel
Trashkid2000
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 561
Erhaltene Danke: 137



BeitragVerfasst: Do 26.08.10 10:49 
Hmmm... gibt es in der Flat-File irgendwelche Indikatoren, welche Elemente gerade drin stehen?

Mal angenommen, das Schema gibt vor, dass sich 3 Personen mit jeweils 3 Attributen und 3 Autos mit weweils 3 Attributen in der Datei bedinden. Die Datei in XML- Form würde also ungefähr so aussehen:
ausblenden XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
<?xml version="1.0" encoding="UTF-8"?>
<Datensaetze>
  <Person Name="Person1" Nachname="Muster1" Verheiratet="ja"/>
  <Person Name="Person2" Nachname="Muster2" Verheiratet="nein"/>
  <Person Name="Person3" Nachname="Muster3" Verheiratet="ja"/>
  <Auto Hersteller="Audi" Typ="A4" Verkauft="nein"/>
  <Auto Hersteller="BMW" Typ="Z3" Verkauft="ja"/>
  <Auto Hersteller="VW" Typ="Golf V" Verkauft="ja"/>
</Datensaetze>


So, und das Flat-File würde dazu ungefär so aussehen: (Fehler ist schon eingebaut)
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
Person1
Muster1
ja
Person2
Muster2
nein
Person3
Muster3
ja
Person4 //Person zu viel
Muster4 //
ja      //
Audi
A4
nein
BMW
Z3
ja
        //Auto zu wenig


So, und nun die grosse Frage: Wie soll der Parser (wenn denn schon einer existieren würde) diesen Fehler erkennen?
Für ihn ist es ja in diesem Fall egal, ob Person oder Auto. Steht ja nichts davor. Laut Schema würde das so durchgehen. Also, ich denke, wenn es in der Flat-File keine Marker oder Abschnitte gibt (wie z.B. in einer INI-Datei), ist das Ganze ziemlich aussichtslos.

Da hast Du ja echt 'ne prickelnde Aufgabe bekommen!

LG, Marko
Drowe Threadstarter
Hält's aus hier
Beiträge: 9

Win XP, Win 7, Win 2008 Server
C# (VS 2008, VS2010)
BeitragVerfasst: Do 26.08.10 12:22 
In deinem Beispiel lässt sich der Fehler nicht abfangen, da es komplett syntaktisch korrekt ist. Für diesen Fall würde ein Tag als Identifier eingefügt werden um eine Unterscheidung zwischen Person und Auto zu ermöglichen. Ich werd nach der Mittagspause einmal ausprobieren, ob sich die Instanz dann noch validieren lässt oder was genau dann passiert.

Daniel

[Edit]
So, die Aufgabe wurde jetzt zugunsten einer anderen Aufgabe für ein paar Tage auf Eis gelegt.

Das Schema wird mit Hilfe eines Tools aus der FlatFile generiert und falls es noch nicht ganz den Anforderungen entspricht werden diese von Hand hinzugefügt. Man muss nicht den Inhalt der Daten auf Korrektheit überprüfen, sondern testen ob die FlatFile syntaktisch korrekt aufgebaut ist, zum Beispiel, dass Einträge die nur einmal vorkommen dürfen tatsächlich auch nur einmal enthalten sind. Die dafür notwendigen Informationen stehen alle im Schema. Das zu schreibende Programm sollte anhand des Schemas die FlatFile durcharbeiten und überprüfen ob alles seine Richtigkeit hat. Und wenn irgendwas nicht in Ordnung ist, soll er die Stelle ausgeben an der der Fehler ist.

Grüße Daniel
[/Edit]
Drowe Threadstarter
Hält's aus hier
Beiträge: 9

Win XP, Win 7, Win 2008 Server
C# (VS 2008, VS2010)
BeitragVerfasst: Di 07.09.10 22:56 
Ich habe einen anderen Ansatz für das Problem gefunden. Der Thread kann geschlossen werden.
Grüße Daniel