Jump to content

VB6 - MSXML2 - Probleme mit leeren Felder


Go to solution Solved by daabm,

Recommended Posts

Hallo Leute,

 

Vielleicht hat ja jemand noch Ahnung von der XML-Geschichte unter VB6 ;)

 

Folgenden Code verwende ich um einen eher schwierig zu lesenden Rattensschwanz-XML-String in einen strukturiertes XML mit Einzügen und Zeilenvorschüben zu verwandeln:

Public Function FormatXmlIndent(vDomOrString As Variant, sResult As String, Optional ByVal bAddStdHeader As Boolean = False) As Boolean
    Dim oWriter         As Object ' MSXML2.MXXMLWriter

    On Error GoTo QH
    
    Set oWriter = CreateObject("MSXML2.MXXMLWriter")
    oWriter.omitXMLDeclaration = True
    oWriter.indent = True
    
    
    With CreateObject("MSXML2.SAXXMLReader")
        Set .contentHandler = oWriter
        '--- keep CDATA elements
        Call .PutProperty("http://xml.org/sax/properties/lexical-handler", oWriter)
        Call .parse(vDomOrString)
    End With
    
    If (bAddStdHeader) Then
        sResult = XMLstandardHeader & vbCrLf & oWriter.Output
    Else
        sResult = oWriter.Output
    End If
    
    '--- success
    FormatXmlIndent = True
    
    Exit Function
QH:
End Function

 

Mein Problem, wie bringe ich dem Objekt bei, bei leeren Feldern sowohl Begin als auch Ende eines Elements auszugeben und nicht nur das Ende? Der Basis-String ist in Ordnung.

Also z.Bsp.

 

<Element1>asdf</Element1> --> wird korrekt ebenso als <Element1>asdf</Element1> ausgegeben

<Element1></Element1> --> wird lediglich zu </Element1>, das einleitende <Element1> fehlt.

 

Normal ist das kein Problem, aber manche Applikationen haben scheinbar Mühe mit dieser Interpretation. Da die Daten extern gehen, habe ich keinen Einfluss darauf. Nun muss ich den Code ergänzen. Das Element ganz weglassen darf ich dagegen nicht. =)

 

Jemand ein Plan wie ich dem Parser das beibringe? Weiss gar nicht ob man auch aktuelle nehmen könnte oder dafür einen Wrapper bauen müsste da .Net. Das einfachste wäre mit der 2er Version.

 

Grüsse und Danke!

 

Link to post

Ah - erwischt :-) Hab ich schon mal gemacht, grad aber nicht greifbar. Und wenn ich mich recht erinnere, hab ich XSLT dafür benutzt. Ich schau nach, Antwort kommt. Zum Verständnis: Dir geht's nur darum, daß ein Endlos-XML "lesbar" formatiert wird, keine Transformation dabei, oder?

Link to post
  • Solution

Here we go - bei mir liegt das in ner Funktion. Ist zwar VBS, aber das ist von VB6 nicht so weit weg, das solltest Du portieren können :-)

Das entscheidende ist das "manuelle" Einfügen von Zeilenumbrüchen an jedem "><" und das Transformieren per Stylesheet mit indent="yes".

Dim strXmlCOMObject
strXmlCOMObject = "Msxml2.DOMDocument.6.0"

Function FormatXML( ByVal XMLObject )
    Dim strXML, objXML, objXSL, strStyleSheet
    Set objXML = WScript.CreateObject( strXMLComObject )
    Set objXSL = WScript.CreateObject( strXMLComObject )
    strXML = Replace( XMLObject.XML, "><", ">" & vbCrLf & "<" )
    objXML.LoadXML strXML
    strStylesheet = _
    "<xsl:stylesheet version=""1.0"" xmlns:xsl=""http://www.w3.org/1999/XSL/Transform"">" & _
    "<xsl:output method=""xml"" indent=""yes""/>" & _
    "<xsl:template match=""/"">" & _
    "<xsl:copy-of select="".""/>" & _
    "</xsl:template>" & _
    "</xsl:stylesheet>"    
    objXSL.loadXML strStylesheet
    objXML.transformNode objXSL
    Return objXML.XML
End Function

 

Link to post

Hi, vielen Dank für die Antwort. Genau so siehts aus. Lesbar machen des "Endlos-Strings".

 

Ich glaube das mit den manuellen Zeilenumbrüchen dürfte es wohl tatsächlich sein.

 

Funktionieren tuts, wenn auch nicht schön.

Aktuell macht er bei leeren Feldern:

<Element1>

</Element1>

 

Bei gefüllten

<Element1>asdf</Element1>

 

Werde ich aber vermutlich schon noch austreiben können und sonst ist es eben nicht wunderschön sondern funktionell =)

 

EDIT/Ergänzung:

Hab das mit Replace noch etwas zu verfeinern versucht um die Situationen aufzufangen. Gibt aber auch immer eine Gurke. Man kriegt entweder abschliessende, Übergeordnete Elemente nicht sauber hin oder das leere Element.

 

Aber das brachte mich auf eine andere Idee. Ich fülle die leeren Felder wenn leer mit einem fiktiven Wert und Ersetze ihn nach dem Formatieren mit "" et voilà tutet auch mit meiner alten Funktion. Manchmal kommt man selbst auf die einfachsten Dinge nicht, auch wenn ich mir eher ein direktes Flag für den Parser gewünscht hätte.

Edited by Weingeist
Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...