Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   XML (https://www.delphipraxis.net/46-xml/)
-   -   Validieren einer XML die 99.te (https://www.delphipraxis.net/198439-validieren-einer-xml-die-99-te.html)

creehawk 2. Nov 2018 11:01

Validieren einer XML die 99.te
 
Moin Moin.

Zum Thema 'Validieren' habe ich in den Posts hier und in der Google Welt allerlei gefunden, aber nichts hilft mit weiter.

Die XML : (Aressenliste.xml)
Code:
<?xml version="1.0"?>
<Adressen xmlns:xsi="http://www.w3.org/2001/XMLSchema-Instance" xsi:schemaLocation="Adressenliste.xsd">
   <Adresse>
      <Index>Käsekuchen</Index>
      <Anrede>Frau</Anrede>
      <Titel>Dr.</Titel>
      <Vorname>Anneliese</Vorname>
      <Nachname>Rampelburger-Meschbach</Nachname>
      <Strasse>Knödelweg</Strasse>
      <Hausnummer>38</Hausnummer>
      <Postleitzahl>47120</Postleitzahl>
      <Ort>Kassebur-Segersheim</Ort>
      <Telefon>04985/83984938</Telefon>
      <Mobil>0175/3986582364</Mobil>
      <EMail>Anneliese@t-online.jo</EMail>
      <Geburtsdatum>12-12-12</Geburtsdatum>
      <Kommentar></Kommentar>
   </Adresse>
</Adressen>
Die XSD: (Adressenliste.xsd)
Code:
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Adressen">
   <xs:complexType>
      <xs:sequence>
         <xs:element name="Adresse" maxOccurs="unbounded" minOccurs="0">
            <xs:complexType>
               <xs:sequence>
                  <xs:element type="xs:int" name="Index"/>
                  <xs:element type="xs:string" name="Anrede"/>
                  <xs:element type="xs:string" name="Titel"/>
                  <xs:element type="xs:string" name="Vorname"/>
                  <xs:element type="xs:string" name="Nachname"/>
                  <xs:element type="xs:string" name="Strasse"/>
                  <xs:element type="xs:integer" name="Hausnummer"/>
                  <xs:element type="xs:int" name="Postleitzahl"/>
                  <xs:element type="xs:string" name="Ort"/>
                  <xs:element type="xs:string" name="Telefon"/>
                  <xs:element type="xs:string" name="Mobil"/>
                  <xs:element type="xs:string" name="EMail"/>
                  <xs:element type="xs:date" name="Geburtsdatum"/>
                  <xs:element type="xs:string" name="Kommentar"/>
               </xs:sequence>
            </xs:complexType>
         </xs:element>
      </xs:sequence>
   </xs:complexType>
</xs:element>
</xs:schema>
Der Code zum validieren:
Code:
uses MSXML, Xml.XMLIntf, XML.XMLDoc, XML.XMLDOM;

function Validate_XML(xmlFile:String): Boolean;
var
  XMLDoc: IXMLDocument;
  T0,T1,T2,T3,T4:String;
begin
  XMLDoc := NewXMLDocument;
  XMLDoc.ParseOptions := [poResolveExternals, poValidateOnParse];
  Result := True;
    try
      XMLDoc.LoadFromFile(xmlFile) ;
      XMLDoc.Active := true;
    except
      on E: EDomParseError do
        begin
          If LastDelimiter('\',E.URL) = 0 then T0:= Copy(E.URL,LastDelimiter('/',E.URL)+1,50);
          If LastDelimiter('/',E.URL) = 0 then T0:= Copy(E.URL,LastDelimiter('\',E.URL)+1,50);
          T1:= 'Bei der Validierung der ' + T0 + ' wurde folgender Fehler festgestellt:' + #13 +#13;
          T2:= E.Reason + #13;                                               // Grund
          T3:= 'Fehler in Zeile : ' + IntToStr(E.Line) + #13;                // Zeile
          T4:= 'Text der Zeile : ' + Trim(E.SrcText) + #13 + #13;           // Zeilentext
          If E.ErrorCode <> -2146697210 then
          begin
          Application.MessageBox(Pchar(T1+T2+T3+T4),Pchar('Validierungsfehler'),16);
          end;
          Result:=False;
        end;
    end;
end;
Trotz des offensichtlichen Fehlers im Feld <Index> (Käsekuchen ist ja wohl kein 32er Integer) läuft die Validierung anstandslos durch.

Was ist da verkehrt? Gibts noch andere Möglichkeiten in Delphi?


creehawk

Delphi 10.2. Tokyo
Windows 10

Fritzew 2. Nov 2018 11:23

AW: Validieren einer XML die 99.te
 
Wir benutzen hier:

Delphi-Quellcode:
unit XMLValidate;


// Requirements ----------------------------------------------------------------
//
// MSXML 4.0 Service Pack 1
// http://www.microsoft.com/downloads/release.asp?releaseid=37176
//
// -----------------------------------------------------------------------------

interface

uses
  SysUtils;

type
  EValidateXMLError = class(Exception)
  private
    FErrorCode: Integer;
    FerrorLine: Integer;
    FReason: string;

  public
    constructor Create(AErrorCode: Integer; const Aline: Integer; const AReason: string);
    property ErrorCode: Integer read FErrorCode;
    property Reason: string read FReason;
  end;

procedure ValidateXMLDoc(const XmlTestFile, SchemaLocation, SchemaNS: WideString); overload;

implementation

uses
  Windows,
  ComObj,
  MSXML2_TLB;

resourcestring
  RsValidateError = 'Validate XML Error (%.8x), Line (%D), Reason: %s';

  { EValidateXMLError }

constructor EValidateXMLError.Create(AErrorCode: Integer; const Aline: Integer; const AReason: string);
begin
  inherited CreateResFmt(@RsValidateError, [AErrorCode, Aline, AReason]);
  FErrorCode := AErrorCode;
  FReason := AReason;
  FerrorLine := Aline;
end;

procedure ValidateXMLDoc(const XmlTestFile, SchemaLocation, SchemaNS: WideString);
var
  xml, xsd: IXMLDOMDocument2;
  cache: IXMLDOMSchemaCollection;
  res: boolean;
  err: IXMLDOMParseError;
begin
  xsd := CoDOMDocument40.Create;
  xsd.async := False;
  xsd.load(SchemaLocation);

  cache := CoXMLSchemaCache40.Create;
  cache.add(SchemaNS, xsd);

  xml := CoDOMDocument40.Create;
  xml.async := False;
  xml.schemas := cache;
  err := nil;
  res := xml.load(XmlTestFile);
  if not res then
    begin
      err := xml.parseError;
      if err <> nil then
        raise EValidateXMLError.Create(err.ErrorCode, err.line, err.Reason);
    end;
end;

end.
Aufruf:

Delphi-Quellcode:
function Txmlmod.internValidatefile(aXmlFileName: string; errorlst: Tstrings): boolean;
var
   lSchemaFilename: string;
begin
   result := false;
   lSchemaFilename := Tpath.combine(Tpath.GetDirectoryName(Globals.XMLData), 'schema_400.xsd');
   try
      ValidateXMLDoc(aXmlFileName, lSchemaFilename, 'http://www.xmlData.com/xmlInvoice/XSD');
      result := true;
   except
      on e: EValidateXMLError do
         begin
            errorlst.add(e.Message);
         end
   end;
end;

creehawk 2. Nov 2018 14:52

AW: Validieren einer XML die 99.te
 
OK, vielen Dank! Der Link übrigens führt zu 'We're sorry, this download is no longer available.', kann man aber anderweitig finden.

Nun sind aber in Windows 10 laut MS die "msxml3.dll" "msxml6.dll" enthalten.

Allerdings frage ich mich dann warum Delphi 10.2 keine funktioniernde Methode beinhaltet respektive anbietet. Die von mir verwendeten Elemente geben ja die verwendeten Funktionen/Prozeduren an, man sollte sie also verwenden können. Auch wenn sie womöglich alt sind.

Ist denn die Anwendung/Verwendung wie oben dargestellt falsch?

creehawk

mjustin 2. Nov 2018 17:27

AW: Validieren einer XML die 99.te
 
Dass es nicht immer funktioniert (je nach Computer / MSXML Version) und welche Besonderheiten man beachten sollte wird hier auf Stackoverflow näher ausgeführt:

Validate XML using Windows DOM and TXMLDocument: doesn't work on some computers

https://stackoverflow.com/questions/...computers?lq=1

p80286 2. Nov 2018 18:27

AW: Validieren einer XML die 99.te
 
Anmerkung zu den Typen:
Die Hausnummer ist keine Zahl z.B. 2b
Die Postleitzahl sollte auch keine Zahl sein w.g. führender Nullen

Gruß
K-H

creehawk 3. Nov 2018 06:10

AW: Validieren einer XML die 99.te
 
Moin Moin.

Den Artikel auf stack hatte ich schon am Wickel und gelesen und getestet. Davon funktioniert nichts.

ipso facto: validieren fällt aus. XML Strukturen die auf w3c feierlich verkündet werden kann ich mit den in Delphi gelieferten Instrumenten quasi nicht nutzen.

Eigentlich hätte ich von Delphi als Entwicklungsumgebung da mehr erwartet.

creehawk

creehawk 3. Nov 2018 10:24

AW: Validieren einer XML die 99.te
 
Ich möchte mich hiermit in aller Form bei allen die diesen Threat gelesen und sogar geantwortet haben entschuldigen.

In tiefster Demut durfte ich nach stundenlangem Suchen feststellen, das die von mir gepostete Version anstandlos funktioniert.

In der XML habe ich den Dateinamen "Adressenliste.xsd" korrekt geschrieben. Gespeichert war das Teil allerdings als "Adresenliste.xsd".

Ich gehe jetzt in den GArten und grab' mich ein.

creehawk

Schokohase 3. Nov 2018 10:28

AW: Validieren einer XML die 99.te
 
Seltsam, auch wenn ich die Dateien korrekt benenne, wird nicht validiert. Und das liegt an dem xsi-Namespace, den hast du falsch geschrieben.

Statt
XML-Code:
<?xml version="1.0"?>
<Adressen xmlns:xsi="http://www.w3.org/2001/XMLSchema-Instance" xsi:schemaLocation="Adressenliste.xsd">
   <Adresse>
      <!-- skipped -->
   </Adresse>
</Adressen>
Muss der wie folgt lauten:
XML-Code:
<?xml version="1.0"?>
<Adressen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="Adressenliste.xsd">
   <Adresse>
      <!-- skipped -->
   </Adresse>
</Adressen>
Eine wirklich aussagekräftige Meldung erhalte ich allerdings erst, wenn die XML-Datei so aussieht:
XML-Code:
<?xml version="1.0"?>
<Adressen xmlns="http://adressenliste.example.com"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://adressenliste.example.com Adressenliste.xsd">
  <Adresse>
    <Index>Käsekuchen</Index>
    <Anrede>Frau</Anrede>
    <Titel>Dr.</Titel>
    <Vorname>Anneliese</Vorname>
    <Nachname>Rampelburger-Meschbach</Nachname>
    <Strasse>Knödelweg</Strasse>
    <Hausnummer>38</Hausnummer>
    <Postleitzahl>47120</Postleitzahl>
    <Ort>Kassebur-Segersheim</Ort>
    <Telefon>04985/83984938</Telefon>
    <Mobil>0175/3986582364</Mobil>
    <EMail>Anneliese@t-online.jo</EMail>
    <Geburtsdatum>12-12-12</Geburtsdatum>
    <Kommentar></Kommentar>
  </Adresse>
</Adressen>
oder auch so
XML-Code:
<?xml version="1.0"?>
<Adressen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:noNamespaceSchemaLocation="Adressenliste.xsd">
  <Adresse>
    <Index>Käsekuchen</Index>
    <Anrede>Frau</Anrede>
    <Titel>Dr.</Titel>
    <Vorname>Anneliese</Vorname>
    <Nachname>Rampelburger-Meschbach</Nachname>
    <Strasse>Knödelweg</Strasse>
    <Hausnummer>38</Hausnummer>
    <Postleitzahl>47120</Postleitzahl>
    <Ort>Kassebur-Segersheim</Ort>
    <Telefon>04985/83984938</Telefon>
    <Mobil>0175/3986582364</Mobil>
    <EMail>Anneliese@t-online.jo</EMail>
    <Geburtsdatum>12-12-12</Geburtsdatum>
    <Kommentar></Kommentar>
  </Adresse>
</Adressen>

Hobbycoder 3. Nov 2018 10:30

AW: Validieren einer XML die 99.te
 
Zitat:

Zitat von creehawk (Beitrag 1417373)
Ich möchte mich hiermit in aller Form bei allen die diesen Threat gelesen und sogar geantwortet haben entschuldigen.

In tiefster Demut durfte ich nach stundenlangem Suchen feststellen, das die von mir gepostete Version anstandlos funktioniert.

In der XML habe ich den Dateinamen "Adressenliste.xsd" korrekt geschrieben. Gespeichert war das Teil allerdings als "Adresenliste.xsd".

Ich gehe jetzt in den GArten und grab' mich ein.

creehawk

Ich glaube es gibt keinen hier, dem das so oder in einer anderen Form nicht selbst schon mal passiert ist.

Nicht jeder ist aber so ehrlich und schreibt das dann hier auch ;-) Von daher, grab das Loch nicht so tief :-D

p80286 3. Nov 2018 10:59

AW: Validieren einer XML die 99.te
 
Zitat:

Zitat von Hobbycoder (Beitrag 1417375)

Nicht jeder ist aber so ehrlich und schreibt das dann hier auch ;-) Von daher, grab das Loch nicht so tief :-D

Der Fehler sitzt immer vor der Tastatur :mrgreen:
Solange ich das beherzige ist alles in Ordnung.

Gruß
K-H

P.S.
Vielen Dank für den Thread, jetzt hab ich die Beispiele um mich endlich mal produktiv mit dem Thema auseinander zu setzen.

creehawk 3. Nov 2018 11:52

AW: Validieren einer XML die 99.te
 
@ schokohase

Hast natürlich recht. "case-sensitive" heißt da ja so schön. Beim rumtesten habe ich das irgendwann wohl verbessert bevor mit die Adresenliste aufgefallen ist.

Was die Sinnhafigkeit der Meldung bei einem Fehler angeht bin ich mit dem Validate_XML Code eigentlich zufrieden.

Und noch was bei Interesse: Setzt man Attribute zu den XML Elementen wie zum Beispiel

<Index typ="int">46374</Index>

muss die XSD in "Salami Slice" aufgebaut sein, Russian Doll/Venetian Dingens geht nicht.

Ok, ist jetzt nicht so direkt auf meinem Mist gewachsen. Ein FreeFormatter aus dem Netz baut aus der XML eine XSD. Da kann man die Formate einstellen, beim probieren hat der Validate_XML Code nur bei Salami mitgespielt.

creehawk


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:09 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz