Welcome, Guest
Username: Password: Remember me
Hier wird Deutsch gesprochen
  • Page:
  • 1

TOPIC:

XML-Parser System.XML 31 Dec 2021 13:25 #20945

  • hsg


  • Posts: 10
  • Moin,

    ich bin gerade am Verzweifeln: Ich muss ein Im-/Export von Daten in einem vorgegeben XML-Format schreiben und dachte, ich nutze dafür die System.XML Lib.
    Im ersten Schritt wollte ich erst mal den Importer schreiben und dachte, dass kann ja nicht so schwer werden. Doch leider scheitere ich schon sehr früh:
    Um zu prüfen, ob die Datei das gewünschte Datenformat habe, muss ich mir einen bestimmten Knoten im XML-Baum ansehen.
    Laut XML-Spy funktioniert bei meiner Beispieldatei der XPath-Ausdruck "GAEB/Award/DP" Der Debugger von XML-Spy liefert mir dann den korrekten Knoten und dessen Value.

    Laden tue ich die XML-Datei über folgendem Code:
    		settings 			:= XmlReaderSettings{}
    		settings:IgnoreWhitespace 	:= TRUE 
    		settings:ASYNC			:= FALSE
    		xr 				:= XmlReader.Create(cFile, settings)
    		oMXML:Load( xr )
    
    oMXML ist dabei vom Typ XMLDocument.
    Das Suchen nach dem Knoten sieht wie folgt aus:
          oNode := oMXML:selectSingleNode( "GAEB/Award/DP" )
          IF oNode != NULL_OBJECT
            cVal	:= oNode:Value
         END IF
    Obwohl ich im Debugger beim oMXML plausiblen Inhalt sehe, geht das Selektieren des Knoten schief und ich bekomme immer NULL zurück.

    Wer kann mich mal auf den richtigen Weg schubsen?
    Guten Rutsch und ein erfolgreiches Jahr 2022 für alle!
    Gruß
    Jörg

    Please Log in or Create an account to join the conversation.

    XML-Parser System.XML 31 Dec 2021 14:05 #20946

    • wriedmann
    • wriedmann's Avatar


  • Posts: 2878
  • Hallo Jörg,
    ich verwende diesen Code hier:
    protected method _FindNode( oXmlNode as XmlNode, cName as string ) as XmlNode
    local oReturn as XmlNode
    
    oReturn	:= null
    if oXmlNode:Name:ToLower() == cName
      oReturn := oXmlNode
    else
      foreach oNode as XmlNode in oXmlNode:ChildNodes
        oReturn := self:_FindNode( oNode, cName )
        if oReturn != null
          exit
        endif
      next
    endif
    
    return oReturn
    Dieser Code ist Teil einer eigenen Klasse, mit der ich die in Italien obbligatorische elektronische Rechnung auswerte. Wenn es notwendig ist, kann ich auch anderen Code bereitstellen. Diese Methode ist aber das Kernstück beim Zerlegen des XML-Dokumentes.
    Wolfgang
    P.S. sorry, bin aktuell in Urlaub, daher kann eine eventuelle Antwort etwas dauern
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    XML-Parser System.XML 31 Dec 2021 14:25 #20948

    • hsg


  • Posts: 10
  • Hatte schon über ähnliches nachgedacht, aber das ist ja eigentlich nicht Sinn der XML-Schnittstelle. Daher hatte ich gehofft, es über die vorhandenen Methoden wie SelectSingleNode oder SelectNodes erledigen zu können.

    Gruß
    Jörg

    Please Log in or Create an account to join the conversation.

    XML-Parser System.XML 01 Jan 2022 09:21 #20956

    • wriedmann
    • wriedmann's Avatar


  • Posts: 2878
  • Hallo Jörg,
    wenn die XML-Dateien aus einer einzigen Quelle kommen, dann mag ein starres Auslesen schon funktionieren.
    Ich ziehe aber die größere Fehlertoleranz einer solchen Suche vor.
    Wolfgang
    Wolfgang Riedmann
    Meran, South Tyrol, Italy

    www.riedmann.it - docs.xsharp.it

    Please Log in or Create an account to join the conversation.

    XML-Parser System.XML 01 Jan 2022 12:22 #20957

    • VR


  • Posts: 51
  • Für das Importieren von XML Dateien würde ich die XDocument Klasse empfehlen (Namespace System.Xml.Linq). Da kann man dann mit Linq auf die XML Knoten zugreifen. Hier ein Beispiel zu den wichtigsten Methoden aus dem Informinds XSharpExamples:

    github.com/InfomindsAg/XSharpExamples/bl...DocumentExamples.prg

    Zum Schreiben von XML Dateien mit XDocument gibt's auch ein Beispiel:

    github.com/InfomindsAg/XSharpExamples/bl...ntExportExamples.prg

    Kleiner Tipp noch: wenn man beim Suchen der Knoten mit Namen Null statt des gewünschten Elements zurück bekommt, könnte das an einem XML-Namespace liegen. ( www.w3schools.com/xml/xml_namespaces.asp )

    Grüße

    Volkmar

    Please Log in or Create an account to join the conversation.

    XML-Parser System.XML 01 Jan 2022 16:23 #20959

    • hsg


  • Posts: 10
  • Hmmm, ich erinnere mich schwach an das Thema Namespace.
    Die XML-Datei fängt wie folg an:
    <?xml version="1.0" encoding="UTF-8"?>
    <GAEB xmlns="http://www.gaeb.de/GAEB_DA_XML/200407">
    Ist also eigentlich kein vollständiger Namespace, wie ich das sehe. Habe trotzdem mal meine Laderoutine wie folgt geändert:
    		settings 			:= XmlReaderSettings{}
    		settings:IgnoreWhitespace 	:= TRUE 
    		settings:ASYNC			:= FALSE
    		xr 				:= XmlReader.Create(cFile, settings)
    		oMXML:Load( xr )     
    		xns				:= XmlNamespaceManager{oMXML:NameTable}
    		IF oMXML:DocumentElement <> NULL
    			oRoot		     := oMXML:DocumentElement
    			FOR i := 0 TO oRoot:Attributes:Count - 1 
    				oAtt		 := oRoot:Attributes[i]
    				IF oAtt:Name == "xmlns" 
    					xns:AddNamespace(oMXML:NameTable:ToString(),oAtt:Value)
    				END IF
    			NEXT
    	        lResult  := TRUE                 
    		END IF
    und gebe den NameSpaceManager beim SelectSingleNode mit an: Gleiches Ergebnis wie bisher (also NULL)
    Wenn nicht noch ein paar Tipps mir auf den richtigen Weg bringen, werde ich mir die XDocument Klasse mal näher ansehen.
    Oder die Knoten selbst suchen.

    Frohes Neues Allen!
    Jörg

    Please Log in or Create an account to join the conversation.

    Last edit: by hsg.

    XML-Parser System.XML 04 Jan 2022 16:26 #21007

    • hsg


  • Posts: 10
  • So, ich habe eine Lösung gefunden: Der XPath-Ausdruck den ich bisher benutzt hatte, scheint hier nicht zu funktionieren. Stattdessen rufe ich jetzt SelectSingleNode wie folgt auf:
    ....
    oNode := oMXML:SelectSingleNode(GetXPathFromRoot( "DP" )) 
    ...
    mit:
    
    METHOD GetXPathFromRoot( cFeld AS STRING) AS STRING
    RETURN "//*[local-name()=""" + cFeld + """]"
    

    Please Log in or Create an account to join the conversation.

    • Page:
    • 1
    Moderators: wriedmann