Autor Thema: Import XML mit NotesDOMParser class  (Gelesen 4719 mal)

Offline manderson

  • Junior Mitglied
  • **
  • Beiträge: 68
    • manderson.de
Import XML mit NotesDOMParser class
« am: 10.05.12 - 10:40:33 »
Guten Morgen!

nach dem ich jetzt xml exportieren kann, will ich auch ein Import einbauen. Habe bereits herausgefunden dass dies wohl mit der NotesDOMParser class machbar ist. Ich habe zum Einstieg ins Thema das Beispiel von IBM verwendet:

 http://publib.boulder.ibm.com/infocenter/domhelp/v8r0/index.jsp?topic=%2Fcom.ibm.designer.domino.main.doc%2FH_EXAMPLES_NOTESDOMPARSER_CLASS_EX.html

Doch wenn ich das Beispiel ausführe enthält die erstellte Datei folgenden Text:
Zitat
DOM Parser Report - Walk Tree agent
errh: 4602:  DOM parser operation failed

Leider werde ich nicht daraus schlau ob meine XML Datei nicht ordnungsgemäß Strukturiert ist (was aber eigentlich sein müsste) oder der Fehler wo anders liegt.  ???

Kann mir jemand dazu was sagen?

Offline manderson

  • Junior Mitglied
  • **
  • Beiträge: 68
    • manderson.de
Re: Import XML mit NotesDOMParser class
« Antwort #1 am: 10.05.12 - 11:05:21 »
Okay, mein Fehler ein kleiner Fehler (Groß/Kleinschreibung) in der xml war doch der Ausschlaggeber *ups*

Offline flaite

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.966
    • mein del.icio.us
Re: Import XML mit NotesDOMParser class
« Antwort #2 am: 10.05.12 - 11:29:54 »
Du kannst selbsterstellte xml-Dokumente in z.B. das hier reinwerfen zum Testen.
http://www.w3schools.com/xml/xml_validator.asp
Wir sprechen hier über das Feld über dem "validate" Knopf.
Gibt auch offenbar aussagekräftigere Fehlermeldung als Notes.
Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile

Offline manderson

  • Junior Mitglied
  • **
  • Beiträge: 68
    • manderson.de
Re: Import XML mit NotesDOMParser class
« Antwort #3 am: 10.05.12 - 12:19:49 »
Danke habs mit den validator von w3 gemerkt - http://validator.w3.org/

Lese gerade dieses Thema (http://atnotes.de/index.php/topic,45337.0.html) und wenn ich es richtig verstehe kann ich diesen Block in das Beispiel von IBM einfügen um ein neues Dokument anzulegen und auch die Nodes in die Dokumente einzuschreiben? 

Code
Case DOMNODETYPE_ELEMENT_NODE:    
         
Dim doc As NotesDocument
Dim session As NotesSession
Dim db As NotesDatabase
Set session = New NotesSession   
Set db = session.CurrentDatabase

If node.nodename = "machineID" Then
 Set doc = db.CreateDocument
 doc.form = "all"
End If 

Doch irgendwie kommt dabei nicht herraus wenn ich dies in den walkTree abschnitt setze ...

Offline manderson

  • Junior Mitglied
  • **
  • Beiträge: 68
    • manderson.de
Re: Import XML mit NotesDOMParser class
« Antwort #4 am: 10.05.12 - 16:08:40 »
Sieht jemand den fehler  ???

Code
   Case DOMNODETYPE_ELEMENT_NODE:        ' Most nodes are Elements
      domParser.Output("Element node: "+node.NodeName )
      Set elt = node
      
	    Dim doc As NotesDocument
	    Dim session As NotesSession
	    Dim db As NotesDatabase
	    Set session = New NotesSession   
	    Set db = session.CurrentDatabase
	    		
	    If node.nodename = "machineID" Then
	      Set doc = db.CreateDocument     
	      doc.form = "form_machine"
	      doc.machineId = Node.Firstchild.Nodevalue
	      Call doc.Save( True, True )
	    End if
 	          
	    If node.nodename = "machineManufacturer" Then
	      doc.form = "form_machine"	  
	      doc.machineManufacturer = Node.Firstchild.Nodevalue
	      Call doc.Save( True, True )	      
     	 End If  

Es wird ein neus Dokument und der Eintrag für machineID erstellt, aber machineManufacturer bleibt leer...

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Re: Import XML mit NotesDOMParser class
« Antwort #5 am: 10.05.12 - 18:53:20 »
Das ganze Teil läuft sicherlich in einer Schleife.

Beim ersten Durchlauf, bei dem nodename vermutlich "machineID" ist, wird doc dimensioniert, doc erstellt, die Felder belegt und schließlich gespeichert.

Beim zweiten Durchlauf, bei dem nodename "machineManufacturer" ist, wird doc wieder dimensioniert, nicht erstellt, Feldwerte hineingeschrieben und gespeichert.

Vermutlich hast Du oben in Deinem Script ein On Error Resume Next (-> zu deutsch, "auch wenns knallt, Augen zu und durch"), sonst müsste Dir das Script mit einem Object variable not set aussteigen.

Das Dim doc As NotesDocument darf auf keinem Fall in der Schleife stehen. Auch die anderen Dim's gehören da nicht hin, führen aber vermutlich nicht zu einem Fehler, sondern kosten nur Rechenzeit. Möglicherweise vernichtet das Dim db auch das doc, müsste man ausprobieren, bzw. besser, raus aus der Schleife damit.

Wenn doc korrekt definiert wäre, sehe ich noch folgende Probleme im Script

Wenn machineManufacturer vor machineID im XML steht, wird kein Dokument erstellt, denn das passiert nur bei machineID (möglich, dass die Datei das so hergibt, kann ich nicht beurteilen). Object variable not set wäre der logische Folgefehler.

Bei jeder Veränderung des Dokuments (neues Feld) wird das Dokument gespeichert, auch das kostet Rechenzeit. Dass jedesmal die Form mit dem gleichen Wert überschrieben wird, ist eigentlich nicht kritisch, zeugt aber von einem suboptimalen Script.

Richtig kann es also nur so sein:

Dokument erstellen
Standardfelder füllen (z.B. Form)
Alle Felder (Items) zum Dokument füllen
Nächstes Dokument? -> Dokument speichern, neues Dokument erstellen
Standardfelder füllen (z.B. Form)
Alle Felder (Items) zum neuen Dokument füllen
usw.



Offline manderson

  • Junior Mitglied
  • **
  • Beiträge: 68
    • manderson.de
Re: Import XML mit NotesDOMParser class
« Antwort #6 am: 11.05.12 - 10:33:03 »
Guten Morgen!

Habe die DIMs aus der Schleife entfernt, aber das bringt es auch noch nicht, wäre ja auch zu schön gewesen :) Kurz noch: machineID steht in der xml vor machineManufacturer. ;)

Wenn ich mit den debugger Schritt für Schritt durch gehe, sehe ich auch das ein Wert für machineManufacturer bei node -> firstchild  vorhanden ist. Lasse ich bei machineManufacturer, ähnlich wie für machineID ein neues Dokument erstellen, dann trägt er den Wert für machineManufacturer im neuen Dokument auch ein. Also irgendwo verlieren ich also den Zugriff auf das frisch erstellte Dokument oder liegt ich da falsch? Ist der call save befehl daran schuld? habe es auch schon nur bei machineManufacturer, sowie auserhalb der Schleife mal rein gepackt aber kein Erfolg.

Hier mal meine Daten:

Decleration

Code
Dim domParser As NotesDOMParser
Dim LF As String
Public doc As NotesDocument

Zitat
Sub Initialize

  Dim session As NotesSession

  Dim db As NotesDatabase

  Dim inputStream As NotesStream, outputStream As NotesStream

  Dim docNode As NotesDOMDocumentNode

  

  Dim origXML As String, outputFile As String

  origXML = "c:\dxl\xmldom.xml"

  outputFile = "c:\dxl\DOMtree.txt"

  

  Dim header As String

  header = "Walk Tree agent"

  LF = Chr(13)+Chr(10)

  

  On Error Goto errh

  

  Set session = New NotesSession    

  Set db = session.CurrentDatabase

  

  'create the output file

  Set outputStream =session.CreateStream

  outputStream.Open (outputFile)

  outputStream.Truncate

  

  'write report title

  outputStream.WriteText ("DOM Parser Report - " )

  outputStream.WriteText (header+LF)

  

  'open the XML file

  Set inputStream = session.CreateStream

  inputStream.Open (origXML)

  If inputStream.Bytes = 0 Then

    outputStream.WriteText (origXML+" is empty"+LF)

    Goto results

  End If

  

  'create DOM parser and process

  Set domParser=session.CreateDOMParser(inputStream, outputStream)

  domParser.Process

  

  'get the document node

  Set docNode = domParser.Document

  

  Call walkTree(docNode)

  

results:

  Call outputStream.Close

  Exit Sub

errh:

  outputStream.WriteText ("errh: "+Cstr(Err)+":  "+Error+LF)

  Resume results

End Sub

Un der  Walktree  + meine kaputter Block

Code
Sub walkTree ( node As NotesDOMNode)
  Dim child As NotesDOMNode
  Dim elt As NotesDOMNode
  Dim attrs As NotesDOMNamedNodeMap
  Dim a As NotesDOMAttributeNode
  Dim piNode As NotesDOMProcessingInstructionNode
  
	Dim doc As NotesDocument
	Dim session As NotesSession
	Dim db As NotesDatabase
	Set session = New NotesSession   
	Set db = session.CurrentDatabase

  LF = Chr(13)+Chr(10)
 
  If Not node.IsNull Then 
    Select Case node.NodeType
    Case DOMNODETYPE_DOCUMENT_NODE:        ' If it is a Document node
      domParser.Output( "Document node: "+node.Nodename )
      Set child = node.FirstChild   ' Get the first node
      Dim numChildNodes As Integer
      numChildNodes = node.NumberOfChildNodes
      domParser.Output(" has "+Cstr(numChildNodes)+" Child Nodes"+LF)
     
      While numChildNodes > 0
        Set child = child.NextSibling ' Get next node
        numChildNodes = numChildNodes - 1
        Call walkTree(child)
      Wend
     
    Case DOMNODETYPE_DOCUMENTTYPE_NODE:   ' It is a <!DOCTYPE> tag
      domParser.Output("Document Type node: "+ node.NodeName+LF)
     
    Case DOMNODETYPE_TEXT_NODE:           ' Plain text node
      domParser.Output("Text node: "+node.NodeValue+LF)
	 
	      
    Case DOMNODETYPE_ELEMENT_NODE:        ' Most nodes are Elements
      domParser.Output("Element node: "+node.NodeName )
      Set elt = node
      
	    
	 
     'XMl Daten in die db schreiben   
		
	    If node.nodename = "machineID" Then
	      Set doc = db.CreateDocument     
	      doc.form = "form_machine"
	      'doc.machineId = Node.Firstchild.Nodevalue
	      Call doc.ReplaceItemValue("machineID", Node.Firstchild.Nodevalue)
	      Call doc.Save(true, true)
	      End If
	              
	  	If node.nodename = "machineManufacturer" Then
	      
	      doc.form = "form_machine"	  
	      Call doc.ReplaceItemValue("machineManufacturer", Node.Firstchild.Nodevalue)
	      Call doc.Save(True, true)
     	End If 
	    
   

     
      Dim numAttributes As Integer, numChildren As Integer
      numAttributes = elt.attributes.numberofentries
      domParser.Output(" has "+Cstr(numAttributes)+" Attributes"+LF)
     
      Set attrs = elt.Attributes     ' Get attributes
     
      Dim i As Integer
      For i = 1 To numAttributes     ' Loop through them
        Set a = attrs.GetItem(i)
        ' Print attr. name & value
        domParser.Output("Attribute "+a.NodeName+": "+a.NodeValue+LF)
      Next
     
      numChildren =  elt.NumberOfChildNodes
      Set child = elt.FirstChild     ' Get child
      While numChildren > 0
        Call walkTree(child)
        Set child = child.NextSibling   ' Get next child
        numChildren = numChildren - 1
      Wend
      domParser.Output( elt.nodeName+LF)
     
    Case DOMNODETYPE_COMMENT_NODE:                ' Comments
      domParser.Output("Comment node: "+node.NodeValue+LF)
     
    Case DOMNODETYPE_PROCESSINGINSTRUCTION_NODE:  ' Handle PI nodes
      Set piNode = node
      domParser.Output("Processing Instruction node: " )
      domParser.Output(" with Target  "+piNode.Target+_
      " and Data "+piNode.Data+LF)
     
    Case DOMNODETYPE_CDATASECTION_NODE:           ' CDATA sections
      domParser.Output("CDATA Section node: "+node.NodeName)
      domParser.Output(" has value of "+node.NodeValue+LF)
     
    Case DOMNODETYPE_ENTITYREFERENCE_NODE:        ' Handle entities
      domParser.Output("Entity Reference node: "+node.NodeName+LF)
      

     
    Case Else:
      domParser.Output("Ignoring node: "+Cstr(node.NodeType)+LF)
      
    
     
    End Select  'node.NodeType
  End If        'Not node.IsNull
End Sub
« Letzte Änderung: 11.05.12 - 10:46:47 von manderson »

Offline manderson

  • Junior Mitglied
  • **
  • Beiträge: 68
    • manderson.de
Re: Import XML mit NotesDOMParser class
« Antwort #7 am: 11.05.12 - 10:57:33 »
hmm DOMtree.txt spuckt nun folgendes aus:

Zitat
DOM Parser Report - Walk Tree agent
Document node: #document has 2 Child Nodes
Element node: machineList has 0 Attributes
Text node:
      
Element node: machine has 0 Attributes
Text node:
         
Element node: machineID has 0 Attributes
Text node: 123456Machine
machineID
Text node:
         
Element node: machineManufacturererrh: 91:  Object variable not set

Offline manderson

  • Junior Mitglied
  • **
  • Beiträge: 68
    • manderson.de
Re: Import XML mit NotesDOMParser class
« Antwort #8 am: 11.05.12 - 11:44:41 »
Ohne Dim doc As NotesDocument geht es... ich könnte schrein....  ;D

Naja so lernt man halt

Offline Peter Klett

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.713
  • Geschlecht: Männlich
Re: Import XML mit NotesDOMParser class
« Antwort #9 am: 11.05.12 - 19:17:09 »
Völlig logisch. Du hast doc global declariert und in Deiner WalkTree-Funktion rufst Du die Funktion selbst wieder auf: Call walkTree(child)

Der rekursive Aufruf soll das gleiche Dokument bearbeiten, und mit dem zusätzlichen und unnötigen Dim doc As NotesDocument in der Funktion hast Du das alte doc im Speicher vernichtet, daran hat das doc.Save keine Schuld.

Das ist also Deine Schleife, innerhalb der Du doc nicht neu dimensionieren darfst. Im ersten Versuch hattest Du es nur aus der Case-Bedingung herausgenommen, aber nicht aus der Schleife. Beim rekursiven Aufruf einer Funktion, die mit dem gleichen Dokument arbeiten soll, musst Du es entweder global deklarieren (wie Du es getan hast) oder es der Funktion als Parameter mitgeben, was ich persönlich eleganter finde (nur "Bauchgefühl"). 

Offline ata

  • Freund des Hauses!
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 5.092
  • Geschlecht: Männlich
  • drenaiondrufflos
    • Anton Tauscher Privat
Re: Import XML mit NotesDOMParser class
« Antwort #10 am: 12.05.12 - 09:26:14 »
... ich würde es als Parameter übergeben - ist linearer...
Grüßle Toni :)

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz