XML einlesen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
kunstlust
Beiträge: 259
Registriert: 12.04.2012 23:47
Wohnort: Hannover
Kontaktdaten:

XML einlesen

Beitrag von kunstlust »

Ich möchte gerne eine XML eines Druckers auslesen und haben mir als Grundlage diesen Code als Hilfe genommen http://rosettacode.org/wiki/XML/Input#PureBasic
Ich verstehe nur noch nicht, wie ich zB. von "<JOB_NAME value='Pubebasic.pdf'/>" das Pubebasic.pdf in die "MessageRequester("ACCOUNTING_INFO", JOB_NAME\s)" bekommen und würde mich um hilfe sehr freuen.

Danke :D

Code: Alles auswählen

Define JOB_NAME.String, src$

src$ =  "<ACCOUNTING_INFO>"
src$ + "<JOB_NAME value='Pubebasic.pdf'/>"
src$ + "<UUID value='30384F30-3930-3037-4f8d-75db0000006c'/>"
src$ + "<USER_DEFINED value=''/>"
src$ + "<APPLICATION_ID value='PIDHPDRL000'/>"
src$ + "<ACCOUNT_ID value=''/>"
src$ + "<TIMESTAMP value='20120417155422'/>"
src$ + "<PRINTING_TIMESTAMP value='20120417155331'/>"
src$ + "<JOB_STATUS value='0'/>"
src$ + "<USER_NAME value=''/>"
src$ + "<SOURCE value='1'/>"
src$ + "<INK_COVERAGE_CATEGORY value='D'/>"
src$ + "<PRINT_QUALITY value='1'/>"
src$ + "<PRINT_TYPE value='1'/>"
src$ + "<PAGES value='1'/>"
src$ + "<COPIES value='1'/>"
src$ + "<PRINTING_TIME units='secondsx10' value='428'/>"
src$ + "<SCANNED_AREA units='sqi' value=''/>"
src$ + "<MEDIA_INFO>"
src$ + "<NAME vendor-name='' media-name='Plain Paper'/>"
src$ + "<QUANTITY units='sqi' value='96'/>"
src$ + "<SIZE units='inchesx3600'>"
src$ + "<WIDTH value='42112'/>"
src$ + "<LENGTH value='29782'/>"
src$ + "</SIZE><SOURCE value=''/>"
src$ + "</MEDIA_INFO><INK_INFO>"
src$ + "<INK_USED units='microliters' value='249'/>"
src$ + "<CONSUME color='Y' quantity='55' ink-type='non-HP Ink'/>"
src$ + "<CONSUME color='C' quantity='50' ink-type='non-HP Ink'/>"
src$ + "<CONSUME color='mk' quantity='103' ink-type='non-HP Ink'/>"
src$ + "<CONSUME color='dg' quantity='43' ink-type='non-HP Ink'/>"
src$ + "<CONSUME color='M' quantity='42' ink-type='non-HP Ink'/>"
src$ + "<CONSUME color='G' quantity='42' ink-type='non-HP Ink'/>"
src$ + "</INK_INFO>"
src$ + "</ACCOUNTING_INFO>"
 

Procedure get_values(*cur_node, nodeName$, attribute$, *valueResults.String)

  Protected result$
 
  While *cur_node
    If XMLNodeType(*cur_node) = #PB_XML_Normal
 
      result$ = GetXMLNodeName(*cur_node)
      If result$ = nodeName$
        If ExamineXMLAttributes(*cur_node)
          While NextXMLAttribute(*cur_node)
            If XMLAttributeName(*cur_node) = attribute$
              If *valueResults <> #Null
                *valueResults\s + XMLAttributeValue(*cur_node) + Chr(13) ;value + carriage-return
              EndIf 
            EndIf
          Wend
        EndIf
      EndIf 
 
    EndIf 
 
    get_values(ChildXMLNode(*cur_node), nodeName$, attribute$, *valueResults)
    *cur_node = NextXMLNode(*cur_node)
  Wend 
EndProcedure
 
CatchXML(0,@src$,Len(src$))
 
If IsXML(0)
  get_values(MainXMLNode(0), "ACCOUNTING_INFO", "JOB_NAME",@JOB_NAME)
  MessageRequester("ACCOUNTING_INFO", JOB_NAME\s)
  FreeXML(0)
EndIf 
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: XML einlesen

Beitrag von STARGÅTE »

Du benutzt die Prozedur nicht richtig.

sowohl "ACCOUNTING_INFO" als auch "JOB_NAME" sind Knoten-Namen, und der Attribut-Name ist "value".

Ich würde an dieser Stelle gleich auf eines meiner Include verweisen: ImportXML - XML als Struktur-Variable laden und lesen

Damit kannst du die XML direkt als Struktur in PB nutzen.
Hier mal die nötigen Zeilen:

Code: Alles auswählen


;- Include

Enumeration
	#ImportXML_File
	#ImportXML_String
EndEnumeration

; Attribut-Name und Wert als Integer, Float und String
Structure XMLAttribute
	Name.s
	Integer.i
	Float.f
	StructureUnion
		Value.s
		String.s
	EndStructureUnion
EndStructure

; Knoten-Name, -Text und -Typ, sowie alle Unterknoten und Attribute
Structure XMLNode
	Name.s
	Text.s
	Type.i
	List *Attributes.XMLAttribute()
	Map Attribute.XMLAttribute(8) ; Aus Sparsamkeit nur 8 Slots
	List *Nodes.XMLNode()
	Map Node.XMLNode(16) ; Aus Sparsamkeit nur 16 Slots
EndStructure

; XML-Struktur mit Hauptknoten und Pfadzugriff
Structure XML
	Main.XMLNode
	Map *Path.XMLNode()
EndStructure

; Intern: Importieren eines XML-Knotens
Procedure ImportXML_Node(*XML.XML, *XMLNode.XMLNode, *Node)
	Protected *Child
	With *XMLNode
		\Type = XMLNodeType(*Node)
		\Name = GetXMLNodeName(*Node)
		\Text = GetXMLNodeText(*Node)
		AddMapElement(*XML\Path(), XMLNodePath(*Node))
		*XML\Path() = *XMLNode
		If ExamineXMLAttributes(*Node)
			While NextXMLAttribute(*Node)
				AddMapElement(\Attribute(), XMLAttributeName(*Node))
				AddElement(\Attributes())
				\Attributes() = @\Attribute()
				\Attribute()\Name    = XMLAttributeName(*Node)
				\Attribute()\String  = XMLAttributeValue(*Node)
				\Attribute()\Integer = Val(XMLAttributeValue(*Node))
				\Attribute()\Float   = ValF(XMLAttributeValue(*Node))
			Wend
		EndIf
		*Child = ChildXMLNode(*Node)
		While *Child
			AddMapElement(\Node(), GetXMLNodeName(*Child), #PB_Map_NoElementCheck)
			AddElement(\Nodes())
			\Nodes() = @\Node()
			ImportXML_Node(*XML, \Node(), *Child)
			*Child = NextXMLNode(*Child)
		Wend
	EndWith
EndProcedure

; Prozedur zum importieren einer XML-Datei als Variable mit Struktur
Procedure ImportXML(*XML.XML, Source.s, Type.i=#ImportXML_File)
	Protected XML.i, Result.i
	Select Type
		Case #ImportXML_File
			XML = LoadXML(#PB_Any, Source)
		Case #ImportXML_String
			XML = CatchXML(#PB_Any, @Source, StringByteLength(Source))
	EndSelect
	If XML
		If XMLStatus(XML) = #PB_XML_Success
			ImportXML_Node(*XML, *XML\Main, MainXMLNode(XML))
			Result = #True
		EndIf
		FreeXML(XML)
	EndIf
	ProcedureReturn Result
EndProcedure


Define Example.XML
Define src$

src$ =  "<ACCOUNTING_INFO>"
src$ + "<JOB_NAME value='Pubebasic.pdf'/>"
src$ + "<UUID value='30384F30-3930-3037-4f8d-75db0000006c'/>"
src$ + "<USER_DEFINED value=''/>"
src$ + "<APPLICATION_ID value='PIDHPDRL000'/>"
src$ + "<ACCOUNT_ID value=''/>"
src$ + "<TIMESTAMP value='20120417155422'/>"
src$ + "<PRINTING_TIMESTAMP value='20120417155331'/>"
src$ + "<JOB_STATUS value='0'/>"
src$ + "<USER_NAME value=''/>"
src$ + "<SOURCE value='1'/>"
src$ + "<INK_COVERAGE_CATEGORY value='D'/>"
src$ + "<PRINT_QUALITY value='1'/>"
src$ + "<PRINT_TYPE value='1'/>"
src$ + "<PAGES value='1'/>"
src$ + "<COPIES value='1'/>"
src$ + "<PRINTING_TIME units='secondsx10' value='428'/>"
src$ + "<SCANNED_AREA units='sqi' value=''/>"
src$ + "<MEDIA_INFO>"
src$ + "<NAME vendor-name='' media-name='Plain Paper'/>"
src$ + "<QUANTITY units='sqi' value='96'/>"
src$ + "<SIZE units='inchesx3600'>"
src$ + "<WIDTH value='42112'/>"
src$ + "<LENGTH value='29782'/>"
src$ + "</SIZE><SOURCE value=''/>"
src$ + "</MEDIA_INFO><INK_INFO>"
src$ + "<INK_USED units='microliters' value='249'/>"
src$ + "<CONSUME color='Y' quantity='55' ink-type='non-HP Ink'/>"
src$ + "<CONSUME color='C' quantity='50' ink-type='non-HP Ink'/>"
src$ + "<CONSUME color='mk' quantity='103' ink-type='non-HP Ink'/>"
src$ + "<CONSUME color='dg' quantity='43' ink-type='non-HP Ink'/>"
src$ + "<CONSUME color='M' quantity='42' ink-type='non-HP Ink'/>"
src$ + "<CONSUME color='G' quantity='42' ink-type='non-HP Ink'/>"
src$ + "</INK_INFO>"
src$ + "</ACCOUNTING_INFO>"

If ImportXML(@Example, src$, #ImportXML_String)
	MessageRequester("ACCOUNTING_INFO", Example\Main\Node("JOB_NAME")\Attribute("value")\String)
EndIf 

PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
kunstlust
Beiträge: 259
Registriert: 12.04.2012 23:47
Wohnort: Hannover
Kontaktdaten:

Re: XML einlesen

Beitrag von kunstlust »

Ich Danke dir sehr STARGÅTE, ich habe mir das auf dem Link von dir zuvor schon mal angeschaut, aber noch nicht ganz verstanden, nun denke ich schon.
Vielen Dank für deine Hilfe :bounce:
Benutzeravatar
kunstlust
Beiträge: 259
Registriert: 12.04.2012 23:47
Wohnort: Hannover
Kontaktdaten:

Re: XML einlesen

Beitrag von kunstlust »

Eine bescheidene Frage habe ich aber noch, wie lese ich solche Inhalte aus?

"<FW_Version>KHN_01_00_09.5</FW_Version>"

Code: Alles auswählen

Debug Example\Main\Node("FW_Version")......
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: XML einlesen

Beitrag von ts-soft »

Code: Alles auswählen

If ImportXML(@Example, src$, #ImportXML_String)
   MessageRequester("ACCOUNTING_INFO", Example\Main\Node("FW_Version")\Text)
EndIf
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
kunstlust
Beiträge: 259
Registriert: 12.04.2012 23:47
Wohnort: Hannover
Kontaktdaten:

Re: XML einlesen

Beitrag von kunstlust »

ts-soft leider ist kein Text zu sehen, die verschieden Typen habe ich auch schon probiert, was mache ich nur falsch? :praise:

Code: Alles auswählen

Define Example.XML
Define src$

src$ = "<FW_Version>KHN_01_00_09.5</FW_Version>"

If ImportXML(@Example, src$, #ImportXML_String)
   MessageRequester("FW_Version", Example\Main\Node("FW_Version")\Text)
EndIf

Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: XML einlesen

Beitrag von NicTheQuick »

Ist es nicht eher so?

Code: Alles auswählen

MessageRequester("FW_Version", Example\Main\Text)
Hab's nicht getestet, aber zwei mal "FW_Version" fand ich merkwürdig.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: XML einlesen

Beitrag von ts-soft »

NicTheQuick hat Recht. Der Fehler ist aber nicht meiner, ich bin davon ausgegangen, dieser Text würde sich in der XML
des ersten Sourcs befinden, weil dann wäre mein Beispiel richtig.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: XML einlesen

Beitrag von STARGÅTE »

Da eine XML immer ein Hauptknoten haben muss, hatte ich mich damals dafür entschieden diesen Hauptknoten durch \Main anzusprechen, da es einfacher ist, und etwas kürzer, als dort auch \Node("") zu verwenden.

Auf Änderungswünsche kann ich natürlich eingehen.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: XML einlesen

Beitrag von ts-soft »

Ne, ist schon in Ordnung so. Problem war ja nur, das ich bei der Frage von kunstlust davon ausgegangen bin,
die Zeile befindet sich innerhalb desselben Main, wie im anderen Beispiel. Hätte er dazu gesagt, was man erst
aus seiner nicht funktionierenden Umsetzung entnehmen kann, das es alleinstehend ist, hätte ich auch gleich die
richtige Lösung gefunden :wink:
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Antworten