Seite 1 von 1

XMLNodePath und LinkedList

Verfasst: 01.02.2011 13:43
von PureBuster
Hallo zusammen,

ich habe ein Problemchen mit einer LinkedList von Typ String.

Ich möchte gerne eine Menge Ergebnisse aus XMLNodePath() Abfragen in der Liste ablegen, diese dann sortieren und von doppelten Einträgen bereinigen. Dabei werden die XPath Ausdrücke ziemlich willkürlich abgeschnitten und damit das Ergebnis verfälscht.

Beispiel eines falschen Ergebnisses:

/dmodule/content/refs/refdm[4]/avee/discod
/dmodule/content/refs/refdm[4]/avee/discode

oder auch

/dmodule/content/refs/refdm[4]/avee/incod
/dmodule/content/refs/refdm[4]/avee/incode


Laut PB-Doku sollte XMLNodePath() eigentlich einen String liefern und ich war bislang der Hoffnung, dass ich diesen auch in einer LinkedList() von Typ String ablegen kann???

Code: Alles auswählen





xml_Pfad.s = PathRequester("Verzeichnis der xml-Dateien auswählen", GetHomeDirectory())

NewList Pfade.s()
NewList Fehlerdateien.s()


Procedure.i  search_tag(node_index.i)
  If ChildXMLNode(node_index)
  ProcedureReturn ChildXMLNode(node_index)
  EndIf
  If NextXMLNode(node_index)
  ProcedureReturn NextXMLNode(node_index)
  EndIf
  While ParentXMLNode(node_index)
  If NextXMLNode(ParentXMLNode(node_index))
  ProcedureReturn NextXMLNode(ParentXMLNode(node_index))
  EndIf
  node_index = ParentXMLNode(node_index)
  Wend
  ProcedureReturn 0
EndProcedure

Procedure.i kommentare_entfernen(xml.i)
  
  tag.i = search_tag(MainXMLNode(xml))
  
  While tag And tag <> MainXMLNode(xml)
    If XMLNodeType(tag) = #PB_XML_Instruction Or XMLNodeType(tag) = #PB_XML_Comment
      DeleteXMLNode(tag)
    EndIf  
    tag.i = search_tag(tag)
  Wend
  
EndProcedure

Procedure.i xml_sicher_Laden(Dateiname.s)
  If IsXML(1)
      FreeXML(1)
  EndIf
  If LoadXML(1,Dateiname)
    If XMLStatus(1) = #PB_XML_Success
      
      kommentare_entfernen(1)
      ProcedureReturn 1

    EndIf
        
    Debug XMLError(1)  
  Else
    
    If IsXML(1)
      FreeXML(1)
    EndIf
  EndIf
  
  
  
  
EndProcedure



If OpenWindow(1, #PB_Ignore, #PB_Ignore, 640, 480, "Ausgabefenster" ,#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  ProgressBarGadget(1, 0, 460, 640, 20, 0, 100) 
  SetGadgetColor(1, #PB_Gadget_FrontColor, $0000FF)
  ListViewGadget(2, 0, 0, 640, 420,#PB_ListView_MultiSelect)

  
  ButtonGadget(8, 490, 420, 120, 40, "Auswahl in Zwischenablage kopieren" ,#PB_Button_MultiLine)
  
Else  
  End  
EndIf



Procedure.i Abbrechen()
  Event = WindowEvent()
  If Event = #PB_Event_CloseWindow And EventWindow() = 1
    End
  EndIf
  If  Or Event = #PB_Event_Gadget And EventGadget() = 4
    Abbrechen = 1
  EndIf
EndProcedure 

Procedure.i laufbalken_fortschreiben(status.i=0)
  
  If status.i = 0
    status.i = GetGadgetState(1)
    If status < 100
      status = status + 1
    Else  
      status = 0
    EndIf  
    SetGadgetState(1,status)  
  Else  
    SetGadgetState(1,status)
  EndIf
  Abbrechen()
EndProcedure  


If ExamineDirectory(1, xml_Pfad, "*.xml")
  While NextDirectoryEntry(1)
    laufbalken_fortschreiben()
    xml_nr.i = xml_sicher_Laden(xml_Pfad + "\" + DirectoryEntryName(1))
    If xml_nr
      
      node_index.i = (MainXMLNode(xml_nr))
      
      While search_tag(node_index)
        If XMLNodeType(node_index) = #PB_XML_Normal
          AddElement(Pfade())
          Pfade() = XMLNodePath(node_index)
          ;Debug XMLNodePath(node_index)
          
        EndIf
        
        node_index = search_tag(node_index)
      Wend
      
      FreeXML(xml_nr)
    Else
      AddElement(Fehlerdateien())
      Fehlerdateien() = xml_Pfad + "\" + DirectoryEntryName(1)
    EndIf
    
    
  Wend
Else
  End ;xml-Verzeichnis nicht inirialisiert
EndIf

SortList(Pfade(),#PB_Sort_Ascending)


;Ergebnisliste bereinigen

aktuell.s = ""
If ListSize(Pfade()) >1
  ResetList(Pfade())
  While NextElement(Pfade())
    If Pfade() = aktuell
      DeleteElement(Pfade(),-1)
    EndIf
    
    aktuell = Pfade()
   
  Wend
  
EndIf





ClearGadgetItems(2)

ForEach Pfade()
  laufbalken_fortschreiben()
  AddGadgetItem(2,-1,Pfade())
  ;Debug Pfade()
Next

laufbalken_fortschreiben(100)
SetGadgetColor(1, #PB_Gadget_FrontColor, RGB(0,255,0))

If ListSize(Fehlerdateien())
  ForEach Fehlerdateien()
    Debug Fehlerdateien()
  Next
EndIf

Repeat
  
    Event = WaitWindowEvent()
        If Event = #PB_Event_CloseWindow And EventWindow() = 1 ; If the user has pressed on the close button
      Quit = 1
    EndIf
    
    If Event = #PB_Event_CloseWindow And EventWindow() = 2 ; If the user has pressed on the close button
      CloseWindow(2)
      Quit = 1
    EndIf
    
    If Event = #PB_Event_Gadget And EventGadget() = 8
        ClearClipboard()
        For x = 0 To CountGadgetItems(2) -1
          If GetGadgetItemState(2,x) = #PB_ListIcon_Selected
            
            SetClipboardText(GetClipboardText() + GetGadgetItemText(2,x) + Chr(13))
          EndIf
        Next 
    EndIf
      

    
    
  Until Quit = 1

  



btw: ich kompiliere in unicode

Re: XMLNodePath und LinkedList

Verfasst: 01.02.2011 14:02
von ts-soft
Beispiel noch weiter kürzen und dann den Bug im engl. Forum posten.
Wichtig: Fehler taucht nicht im Debugger auf! (Der zeigt korrekten String)

Re: XMLNodePath und LinkedList

Verfasst: 01.02.2011 16:50
von PureBuster
Ich stelle erst mal hier den abgespeckten Quelltext ein. Keinen Schimmer, wie man sich in dem offiziellen Englischen Formum registrieren soll um posten zu können...

Neben anderen Stellen taucht der Fehler in der Debug-Ausgabe 3.Zeile sowie den beiden letzten Zeilen auf.

Code: Alles auswählen






NewList Pfade.s()



Procedure.i  search_tag(node_index.i)
  If ChildXMLNode(node_index)
  ProcedureReturn ChildXMLNode(node_index)
  EndIf
  If NextXMLNode(node_index)
  ProcedureReturn NextXMLNode(node_index)
  EndIf
  While ParentXMLNode(node_index)
  If NextXMLNode(ParentXMLNode(node_index))
  ProcedureReturn NextXMLNode(ParentXMLNode(node_index))
  EndIf
  node_index = ParentXMLNode(node_index)
  Wend
  ProcedureReturn 0
EndProcedure


xml = CreateXML(#PB_Any)

CreateXMLNode(RootXMLNode(xml))
SetXMLNodeName(MainXMLNode(xml),"TESTTREE")

For x.i = 1 To 1000
  
  lastNode = CreateXMLNode(MainXMLNode(xml))
  SetXMLNodeName(lastNode,"TESTNODEALPHA")
  lastNode = CreateXMLNode(MainXMLNode(xml))
  SetXMLNodeName(lastNode,"TESTNODEBRAVO")
  lastNode = CreateXMLNode(lastNode)
  SetXMLNodeName(lastNode,"TESTNODECHARLIE")
  lastNode = CreateXMLNode(lastNode)
  SetXMLNodeName(lastNode,"TESTNODEDELTA")
  
  
Next x


node_index.i = (MainXMLNode(xml))

While search_tag(node_index)
  If XMLNodeType(node_index) = #PB_XML_Normal
    AddElement(Pfade())
    Pfade() = XMLNodePath(node_index)
    ;Debug XMLNodePath(node_index)
  EndIf
  node_index = search_tag(node_index)
Wend

SortList(Pfade(),#PB_Sort_Ascending)

ForEach Pfade()
  Debug Pfade()
Next




Re: XMLNodePath und LinkedList

Verfasst: 01.02.2011 17:56
von NicTheQuick
Kann ich auch unter Ubuntu 10.04 x64 mit PB 4.50 x64 bestätigen.

Re: XMLNodePath und LinkedList

Verfasst: 01.02.2011 18:02
von cxAlex
Kann ich auch bestätigen.
Win 7 Premium x64 mit PB 4.51 x64/x86 und Windows XP PB 4.51 x86

Gruß, Alex

Re: XMLNodePath und LinkedList

Verfasst: 01.02.2011 18:39
von ts-soft

Re: XMLNodePath und LinkedList

Verfasst: 01.02.2011 19:25
von helpy
Hi,

Ich hab' den Test-Code etwas geändert:

Code: Alles auswählen

;...

node_index.i = (MainXMLNode(xml))

While node_index
  If XMLNodeType(node_index) = #PB_XML_Normal
  	AddElement(Pfade())
  	Pfade() = XMLNodePath(node_index)
  	Debug Pfade()
  	If Pfade() <> XMLNodePath(node_index)
  		Debug "  ==> In LinkList: " + Pfade()
  		Debug "  ==> XMLNodePath: " + XMLNodePath(node_index)
  	EndIf
  EndIf
  node_index = search_tag(node_index)
Wend

End
Da kommt dann folgendes raus:

Code: Alles auswählen

/TESTTREE
/TESTTREE/TESTNODEALPHA
/TESTTREE/TESTNODEBRAVO
/TESTTREE/TESTNODEBRAVO/TESTNODECHARLIE
/TESTTREE/TESTNODEBRAVO/TESTNODECHARLIE/TESTNODEDELTA
/TESTTREE/TESTNODEALPHA[2
  ==> In LinkList: /TESTTREE/TESTNODEALPHA[2
  ==> XMLNodePath: /TESTTREE/TESTNODEALPHA[2]
/TESTTREE/TESTNODEBRAVO[2
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[2
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[2]
/TESTTREE/TESTNODEBRAVO[2]/TESTNODECHARLI
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[2]/TESTNODECHARLI
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[2]/TESTNODECHARLIE
/TESTTREE/TESTNODEBRAVO[2]/TESTNODECHARLIE/TESTNODEDELT
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[2]/TESTNODECHARLIE/TESTNODEDELT
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[2]/TESTNODECHARLIE/TESTNODEDELTA
/TESTTREE/TESTNODEALPHA[3
  ==> In LinkList: /TESTTREE/TESTNODEALPHA[3
  ==> XMLNodePath: /TESTTREE/TESTNODEALPHA[3]
/TESTTREE/TESTNODEBRAVO[3
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[3
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[3]
/TESTTREE/TESTNODEBRAVO[3]/TESTNODECHARLI
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[3]/TESTNODECHARLI
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[3]/TESTNODECHARLIE
/TESTTREE/TESTNODEBRAVO[3]/TESTNODECHARLIE/TESTNODEDELT
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[3]/TESTNODECHARLIE/TESTNODEDELT
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[3]/TESTNODECHARLIE/TESTNODEDELTA
/TESTTREE/TESTNODEALPHA[4
  ==> In LinkList: /TESTTREE/TESTNODEALPHA[4
  ==> XMLNodePath: /TESTTREE/TESTNODEALPHA[4]
/TESTTREE/TESTNODEBRAVO[4
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[4
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[4]
/TESTTREE/TESTNODEBRAVO[4]/TESTNODECHARLI
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[4]/TESTNODECHARLI
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[4]/TESTNODECHARLIE
/TESTTREE/TESTNODEBRAVO[4]/TESTNODECHARLIE/TESTNODEDELT
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[4]/TESTNODECHARLIE/TESTNODEDELT
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[4]/TESTNODECHARLIE/TESTNODEDELTA
/TESTTREE/TESTNODEALPHA[5
  ==> In LinkList: /TESTTREE/TESTNODEALPHA[5
  ==> XMLNodePath: /TESTTREE/TESTNODEALPHA[5]
/TESTTREE/TESTNODEBRAVO[5
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[5
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[5]
/TESTTREE/TESTNODEBRAVO[5]/TESTNODECHARLI
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[5]/TESTNODECHARLI
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[5]/TESTNODECHARLIE
/TESTTREE/TESTNODEBRAVO[5]/TESTNODECHARLIE/TESTNODEDELT
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[5]/TESTNODECHARLIE/TESTNODEDELT
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[5]/TESTNODECHARLIE/TESTNODEDELTA
/TESTTREE/TESTNODEALPHA[6
  ==> In LinkList: /TESTTREE/TESTNODEALPHA[6
  ==> XMLNodePath: /TESTTREE/TESTNODEALPHA[6]
/TESTTREE/TESTNODEBRAVO[6
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[6
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[6]
/TESTTREE/TESTNODEBRAVO[6]/TESTNODECHARLI
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[6]/TESTNODECHARLI
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[6]/TESTNODECHARLIE
/TESTTREE/TESTNODEBRAVO[6]/TESTNODECHARLIE/TESTNODEDELT
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[6]/TESTNODECHARLIE/TESTNODEDELT
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[6]/TESTNODECHARLIE/TESTNODEDELTA
/TESTTREE/TESTNODEALPHA[7
  ==> In LinkList: /TESTTREE/TESTNODEALPHA[7
  ==> XMLNodePath: /TESTTREE/TESTNODEALPHA[7]
/TESTTREE/TESTNODEBRAVO[7
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[7
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[7]
/TESTTREE/TESTNODEBRAVO[7]/TESTNODECHARLI
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[7]/TESTNODECHARLI
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[7]/TESTNODECHARLIE
/TESTTREE/TESTNODEBRAVO[7]/TESTNODECHARLIE/TESTNODEDELT
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[7]/TESTNODECHARLIE/TESTNODEDELT
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[7]/TESTNODECHARLIE/TESTNODEDELTA
/TESTTREE/TESTNODEALPHA[8
  ==> In LinkList: /TESTTREE/TESTNODEALPHA[8
  ==> XMLNodePath: /TESTTREE/TESTNODEALPHA[8]
/TESTTREE/TESTNODEBRAVO[8
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[8
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[8]
/TESTTREE/TESTNODEBRAVO[8]/TESTNODECHARLI
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[8]/TESTNODECHARLI
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[8]/TESTNODECHARLIE
/TESTTREE/TESTNODEBRAVO[8]/TESTNODECHARLIE/TESTNODEDELT
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[8]/TESTNODECHARLIE/TESTNODEDELT
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[8]/TESTNODECHARLIE/TESTNODEDELTA
/TESTTREE/TESTNODEALPHA[9
  ==> In LinkList: /TESTTREE/TESTNODEALPHA[9
  ==> XMLNodePath: /TESTTREE/TESTNODEALPHA[9]
/TESTTREE/TESTNODEBRAVO[9
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[9
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[9]
/TESTTREE/TESTNODEBRAVO[9]/TESTNODECHARLI
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[9]/TESTNODECHARLI
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[9]/TESTNODECHARLIE
/TESTTREE/TESTNODEBRAVO[9]/TESTNODECHARLIE/TESTNODEDELT
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[9]/TESTNODECHARLIE/TESTNODEDELT
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[9]/TESTNODECHARLIE/TESTNODEDELTA
/TESTTREE/TESTNODEALPHA[10
  ==> In LinkList: /TESTTREE/TESTNODEALPHA[10
  ==> XMLNodePath: /TESTTREE/TESTNODEALPHA[10]
/TESTTREE/TESTNODEBRAVO[10
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[10
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[10]
/TESTTREE/TESTNODEBRAVO[10]/TESTNODECHARLI
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[10]/TESTNODECHARLI
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[10]/TESTNODECHARLIE
/TESTTREE/TESTNODEBRAVO[10]/TESTNODECHARLIE/TESTNODEDELT
  ==> In LinkList: /TESTTREE/TESTNODEBRAVO[10]/TESTNODECHARLIE/TESTNODEDELT
  ==> XMLNodePath: /TESTTREE/TESTNODEBRAVO[10]/TESTNODECHARLIE/TESTNODEDELTA
/TESTTREE/TESTNODEALPHA[11]
/TESTTREE/TESTNODEBRAVO[11]
/TESTTREE/TESTNODEBRAVO[11]/TESTNODECHARLIE
/TESTTREE/TESTNODEBRAVO[11]/TESTNODECHARLIE/TESTNODEDELTA

... der Rest ist in Ordnung!
Da sieht man, dass der Fehler nur Auftritt bei "/.../NODE[2]/..." bis "/.../NODE[10]/...".

Der Fehler tritt auch auf, wenn man statt der LinkedList eine String-Variable nimmt.

lg, guido

Re: XMLNodePath und LinkedList

Verfasst: 02.02.2011 12:00
von PureBuster
Ich kann nun nicht auf einen Bugfix warten und hab mir eine Procedure gestrickt, die den Path zurückgibt ohne XMLNodePath() zu verwenden. Das ist natürlich keine Dauerlösung, aber wenn es sonst noch jemand braucht:

Code: Alles auswählen


Procedure.s Tag_tree_Anzahl(node_index.i)
  pfad.s = "/" + GetXMLNodeName(node_index) + Chr(91) + Chr(93)
  
  While ParentXMLNode(node_index) And XMLNodeType(ParentXMLNode(node_index)) <> #PB_XML_Root
    node_index_behalte.i = node_index
    x.i = 0
    If PreviousXMLNode(node_index)
      x.i = 1
    EndIf
    While PreviousXMLNode(node_index)
      If GetXMLNodeName(PreviousXMLNode(node_index)) = GetXMLNodeName(node_index)
      x + 1
      EndIf
      node_index = PreviousXMLNode(node_index)
    Wend
    node_index = node_index_behalte
    If x > 1
      pfad = ReplaceString(pfad,Chr(91) + Chr(93),Chr(91) + Str(x) + Chr(93))
    Else  
      pfad = ReplaceString(pfad,Chr(91) + Chr(93),"")
    EndIf  
    node_index = ParentXMLNode(node_index)
    pfad.s = "/" + GetXMLNodeName(node_index) + Chr(91) + Chr(93) + pfad
  Wend
  
  pfad = ReplaceString(pfad,Chr(91) + Chr(93),"")
  
  ProcedureReturn pfad
  
EndProcedure


Re: XMLNodePath und LinkedList

Verfasst: 02.02.2011 12:29
von helpy
Hi ...

Zum Vergleich: Ich hatte das ganz ähnlich gelöst:

Code: Alles auswählen

Procedure.s XMLNodePathX( *Node )
	Protected nodePath.s, nodeName.s, nodeIndex, *prevNode
	
	If XMLNodeType(*Node) = #PB_XML_Root
		ProcedureReturn "/"
	EndIf
	
	While XMLNodeType(*Node) <> #PB_XML_Root
		nodeIndex = 1
		nodeName = GetXMLNodeName(*Node)
		*prevNode = PreviousXMLNode(*Node)
		While *prevNode
			If nodeName = GetXMLNodeName(*prevNode)
				nodeIndex + 1
			EndIf
			*prevNode = PreviousXMLNode(*prevNode)
		Wend
		
		If nodeIndex > 1
			nodePath = "/" + nodeName + "[" + Str(nodeIndex) + "]" + nodePath
		Else
			nodePath = "/" + nodeName + nodePath
		EndIf
		
		*Node = ParentXMLNode(*Node)
	Wend
	
	ProcedureReturn nodePath
EndProcedure