XML-Gemurkse

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Mok
BotHunter
Beiträge: 1484
Registriert: 26.12.2005 14:14
Computerausstattung: MSI GX780R
Intel Core i5-2410M
Nvidia GT 555M
Windows 7 Home Premium 64 bit
Wohnort:   

XML-Gemurkse

Beitrag von Mok »

Hallo zusammen!

Ich schreibe gerade einen minimalen Packer (für eigene Zwecke... hab nicht vor, daraus etwas großes zu machen) und weil "scriptability" und "ease-of-use" dachte ich mir "Ich bin jetzt ganz schlau, und bau mir 'ne XML-Unterstützung". Nun sitz ich seit einer Stunde hier, halte mich nicht mehr für ganz so schlau, und überlege, ob es nicht einen einfacheren Weg gibt, eine Struktur-Instanz mit XML-Werten zu befüllen. (Eine einfachere Variante gibt's bestimmt, nur hab' ich wieder ein riesen Brett vorm Kopp)

Hier eine Beispiel-XML-Datei:

Code: Alles auswählen

<?xml version="1.0" encoding="utf-8" ?>
<archive>
  <name>package.pkg</name>
  <compression-level>9</compression-level>
  <files basedir="C:\Temp">
    <file name="Program.exe" />
    <file name="Text.txt" />
    <file name="img\image.bmp" />
  </files>
</archive>
Hier mein Gemurks:

Code: Alles auswählen

Structure Package
  Name.s
  CompressionLevel.i
  BaseDir.s
  List Files.s()
EndStructure

Procedure ProcessXML( ID, *Package.Package )
  Protected *ParentNode = MainXMLNode( ID )
  Protected *CurrentNode = *ParentNode
  
  If XMLNodeType( *ParentNode ) = #PB_XML_Normal
    *ChildNode = ChildXMLNode( *CurrentNode )
    
    While *ChildNode <> 0
      Protected Name.s = LCase( GetXMLNodeName(*ChildNode) )
      
      Select Name
        Case "name"
          *Package\Name = GetXMLNodeText( *ChildNode )
          
        Case "compression-level"
          *Package\CompressionLevel = Val( GetXMLNodeText(*ChildNode) )
          
        Case "files"
          If ExamineXMLAttributes( *ChildNode ) And NextXMLAttribute( *ChildNode )
            If LCase( XMLAttributeName(*ChildNode) ) = "basedir"
              *Package\BaseDir = XMLAttributeValue( *ChildNode )
            EndIf
          EndIf
          
          *ChildNode2 = ChildXMLNode( *ChildNode )
          While *ChildNode2 <> 0
            Protected Name2.s = LCase( GetXMLNodeName(*ChildNode2) )
            If ExamineXMLAttributes( *ChildNode2 ) And NextXMLAttribute( *ChildNode2 )
              If LCase( XMLAttributeName(*ChildNode2) ) = "name"
                AddElement(*Package\Files())
                *Package\Files() = XMLAttributeValue( *ChildNode2 )
              EndIf
            EndIf
            *ChildNode2 = NextXMLNode(*ChildNode2)
          Wend
        EndSelect
          
      *ChildNode = NextXMLNode(*ChildNode)
    Wend
  EndIf
EndProcedure
Wenn man nun annimmt, einen HTML-Parser in PB zu schreiben... gar nicht erst dran denken!

Gruß, Mok.
Win 7 Home Premium 64 bit | PureBasic 5.20 - x86 und x86-64 | Firefox [aktuelle stable-Version hier einfügen]
"Jeder macht irgendwann mal Fehler, darum gibt's auch Bleistifte mit Radiergummi." --Carl
Benutzeravatar
Kiffi
Beiträge: 10711
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: XML-Gemurkse

Beitrag von Kiffi »

hier mal ein wenig ausführlicher und damit (hoffentlich)
verständlicher(?):

Code: Alles auswählen

EnableExplicit

Define XML.s
Define oXML
Define RootNode
Define ArchiveNode
Define NameNode
Define CompressionLevelNode
Define NodeCounter
Define FileNode

XML + "<?xml version='1.0' encoding='utf-8' ?> "
XML + "<archive>"
XML + "  <name>package.pkg</name>"
XML + "  <compression-level>9</compression-level>"
XML + "  <files basedir='C:\Temp'>"
XML + "    <file name='Program.exe' />"
XML + "    <file name='Text.txt' />"
XML + "    <file name='img\image.bmp' />"
XML + "  </files>"
XML + "</archive>"

oXML = CatchXML(#PB_Any, @XML, Len(XML))

If oXML = 0
  End
EndIf

RootNode = RootXMLNode(oXML)

ArchiveNode = XMLNodeFromPath(RootNode, "archive")

If ArchiveNode
  
  NameNode = XMLNodeFromPath(ArchiveNode, "name")
  If NameNode 
    Debug "name: " + GetXMLNodeText(NameNode)
  EndIf
  
  CompressionLevelNode = XMLNodeFromPath(ArchiveNode, "compression-level")
  If CompressionLevelNode
    Debug "compression-level: " + GetXMLNodeText(CompressionLevelNode)
  EndIf
  
  NodeCounter = 1
  
  Repeat
    
    FileNode = XMLNodeFromPath(ArchiveNode, "files/file[" + Str(NodeCounter) + "]")
    
    If FileNode = 0 
      Break
    EndIf
    
    Debug "filename nr." + Str(NodeCounter) + ": " + GetXMLAttribute(FileNode, "name")
    
    NodeCounter + 1
    
  ForEver
  
  
EndIf

FreeXML(oXML)
Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Re: XML-Gemurkse

Beitrag von Kukulkan »

Yep, einfache XML und JSON Strukturen baue ich mir auch am liebsten direkt per String zusammen. Ist schneller und einfacher.

Meiner Meinung nach ist das Zusammenbauen mit den XML Funktionen nur für grössere Strukturen Sinnvoll oder wenn in bestehende Strukturen Elemente eingefügt werden sollen.

Grüße,

Kukulkan
Antworten