Can the XML lib handle this?

Just starting out? Need help? Post your questions and find answers here.
User avatar
kpeters58
Enthusiast
Enthusiast
Posts: 341
Joined: Tue Nov 22, 2011 5:11 pm
Location: Kelowna, BC, Canada

Can the XML lib handle this?

Post by kpeters58 »

...
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName">ACME Software Inc.</VersionInfoKeys>
<VersionInfoKeys Name="FileDescription">ACME TimeCard Import</VersionInfoKeys>
<VersionInfoKeys Name="InternalName">ACME_TcImp.dll</VersionInfoKeys>
<VersionInfoKeys Name="LegalCopyright">Copyright © 2021 ACME Software Group Inc.</VersionInfoKeys>
<VersionInfoKeys Name="ProductName">ACME Import Module</VersionInfoKeys>
<VersionInfoKeys Name="ProductVersion">2.10.1.1</VersionInfoKeys>
</VersionInfoKeys>
...
Fairly easy to get the first attribute line - but what if I was after the 'LegalCopyright' entry? What am I missing?

Code: Select all

    *node = XMLNodeFromPath(RootXMLNode(#XML), "Project/ProjectExtensions/BorlandProject/Delphi.Personality/VersionInfoKeys/VersionInfoKeys")
    If (*node)
      Debug GetXMLAttribute(*node, "Name")
      Debug GetXMLNodeText(*node)
    ; SetXMLAttribute(*Node, "Name", "new_string")
    Else
      Debug "No such node!"
    EndIf
PB 5.73 on Windows 10 & OS X High Sierra
User avatar
TI-994A
Addict
Addict
Posts: 2741
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Can the XML lib handle this?

Post by TI-994A »

kpeters58 wrote:
...
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName">ACME Software Inc.</VersionInfoKeys>
<VersionInfoKeys Name="FileDescription">ACME TimeCard Import</VersionInfoKeys>
<VersionInfoKeys Name="InternalName">ACME_TcImp.dll</VersionInfoKeys>
<VersionInfoKeys Name="LegalCopyright">Copyright © 2021 ACME Software Group Inc.</VersionInfoKeys>
<VersionInfoKeys Name="ProductName">ACME Import Module</VersionInfoKeys>
<VersionInfoKeys Name="ProductVersion">2.10.1.1</VersionInfoKeys>
</VersionInfoKeys>
...
Fairly easy to get the first attribute line - but what if I was after the 'LegalCopyright' entry?
The XML tree must be iterated through with the NextXMLNode() function, like so:

Code: Select all

; create an example XML tree as per OP 
;
xml = CreateXML(#PB_Any) 
mainNode = CreateXMLNode(RootXMLNode(xml), "VersionInfoKeys") 

Restore xmlData
For i = 0 To 5
  Read.s subNodeID$
  Read.s subNodeValue$
  item = CreateXMLNode(mainNode, "VersionInfoKeys") 
  SetXMLAttribute(item, "Name", subNodeID$) 
  SetXMLNodeText(item, subNodeValue$)
Next i

DataSection
xmlData:
  Data.s "CompanyName", "ACME Software Inc."
  Data.s "FileDescription", "ACME TimeCard Import"
  Data.s "InternalName", "ACME_TcImp.dll"
  Data.s "LegalCopyright", "Copyright © 2021 ACME Software Group Inc."
  Data.s "ProductName", "ACME Import Module"
  Data.s "ProductVersion", "2.10.1.1"
EndDataSection


; iterate through the XML tree and extract the values
;
*node = ChildXMLNode(MainXMLNode(xml))
While *node   
  Debug GetXMLAttribute(*node, "Name") + ": " + GetXMLNodeText(*node)
  *node = NextXMLNode(*node)  
Wend 
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
User avatar
helpy
Enthusiast
Enthusiast
Posts: 552
Joined: Sat Jun 28, 2003 12:01 am

Re: Can the XML lib handle this?

Post by helpy »

Quote from above:

Code: Select all

<VersionInfoKeys>
  <VersionInfoKeys Name="CompanyName">ACME Software Inc.</VersionInfoKeys>
  ...
  <VersionInfoKeys Name="ProductVersion">2.10.1.1</VersionInfoKeys>
</VersionInfoKeys>
I would change the child keys of VersionInfoKeys from VersionInfoKeys to VersionInfoKey:

Code: Select all

<VersionInfoKeys>
  <VersionInfoKey Name="CompanyName">ACME Software Inc.</VersionInfoKey>
  ...
  <VersionInfoKey Name="ProductVersion">2.10.1.1</VersionInfoKey>
</VersionInfoKeys>
Windows 10 / Windows 7
PB Last Final / Last Beta Testing
User avatar
kpeters58
Enthusiast
Enthusiast
Posts: 341
Joined: Tue Nov 22, 2011 5:11 pm
Location: Kelowna, BC, Canada

Re: Can the XML lib handle this?

Post by kpeters58 »

helpy wrote:Quote from above:

Code: Select all

<VersionInfoKeys>
  <VersionInfoKeys Name="CompanyName">ACME Software Inc.</VersionInfoKeys>
  ...
  <VersionInfoKeys Name="ProductVersion">2.10.1.1</VersionInfoKeys>
</VersionInfoKeys>
I would change the child keys of VersionInfoKeys from VersionInfoKeys to VersionInfoKey:

Code: Select all

<VersionInfoKeys>
  <VersionInfoKey Name="CompanyName">ACME Software Inc.</VersionInfoKey>
  ...
  <VersionInfoKey Name="ProductVersion">2.10.1.1</VersionInfoKey>
</VersionInfoKeys>

So would I - but since this is part of a Delphi project file, there is little I can do to make this right ... :(
PB 5.73 on Windows 10 & OS X High Sierra
User avatar
kpeters58
Enthusiast
Enthusiast
Posts: 341
Joined: Tue Nov 22, 2011 5:11 pm
Location: Kelowna, BC, Canada

Re: Can the XML lib handle this?

Post by kpeters58 »

Thanks, I had tried that but I made the crucial mistake of not realizing that NextXMLNode returns the next node and not just a boolean value
PB 5.73 on Windows 10 & OS X High Sierra
User avatar
helpy
Enthusiast
Enthusiast
Posts: 552
Joined: Sat Jun 28, 2003 12:01 am

Re: Can the XML lib handle this?

Post by helpy »

A little test example:

Code: Select all

EnableExplicit

Procedure CreateXmlExample()
	Protected xml
	Protected node, i, item
	Protected subNodeID.s, subNodeValue.s
	; create an example XML tree as per OP
	; 
	xml = CreateXML(#PB_Any)
	node = CreateXMLNode(RootXMLNode(xml), "Project")
	node = CreateXMLNode(node, "ProjectExtensions")
	node = CreateXMLNode(node, "BorlandProject")
	node = CreateXMLNode(node, "Delphi.Personality")
	node = CreateXMLNode(node, "VersionInfoKeys")
	
	Restore xmlData
	For i = 0 To 5
		Read.s subNodeID
		Read.s subNodeValue
		item = CreateXMLNode(node, "VersionInfoKeys")
		SetXMLAttribute(item, "Name", subNodeID)
		SetXMLNodeText(item, subNodeValue)
	Next i
	
	ProcedureReturn xml
EndProcedure

Procedure XMLNodeFromPathWithAttribute(ParentNode, Path.s, AttributeName.s, AttributeValue.s)
	Protected nthIndex, nthNode, nthPath.s
	Protected nodeResult
	
	Repeat
		nthIndex + 1
		nthPath = path + "[" + Str(nthIndex) + "]"
		nthNode = XMLNodeFromPath(ParentNode, nthPath)
		If Not nthNode : Break : EndIf
		If GetXMLAttribute(nthNode, AttributeName) = AttributeValue
			nodeResult = nthNode
			Break
		EndIf
	ForEver
		
	ProcedureReturn nodeResult
EndProcedure


Define xmlExample, i, infoNode, subNodeID.s, subNodeValue.s
Define VersionKeys

xmlExample = CreateXmlExample()

Debug "First Test"
Restore xmlData
For i = 0 To 5
	Read.s subNodeID
	Read.s subNodeValue
	infoNode = XMLNodeFromPathWithAttribute(RootXMLNode(xmlExample),
	                                        "Project/ProjectExtensions/BorlandProject/Delphi.Personality/VersionInfoKeys/VersionInfoKeys",
	                                        "Name", subNodeID)
	Debug LSet(subNodeID + " ", 20, ".") + " " + GetXMLNodeText(infoNode)
Next i

Debug ""
Debug "Second Test"
VersionKeys = XMLNodeFromPath(RootXMLNode(xmlExample), 
                              "/Project/ProjectExtensions/BorlandProject/Delphi.Personality/VersionInfoKeys")
If VersionKeys
	Restore xmlData
	For i = 0 To 5
		Read.s subNodeID
		Read.s subNodeValue
		infoNode = XMLNodeFromPathWithAttribute(VersionKeys, "VersionInfoKeys", "Name", subNodeID)
		Debug LSet(subNodeID + " ", 20, ".") + " " + GetXMLNodeText(infoNode)
	Next i
EndIf

DataSection
	xmlData:
	Data.s "CompanyName", "ACME Software Inc."
	Data.s "FileDescription", "ACME TimeCard Import"
	Data.s "InternalName", "ACME_TcImp.dll"
	Data.s "LegalCopyright", "Copyright © 2021 ACME Software Group Inc."
	Data.s "ProductName", "ACME Import Module"
	Data.s "ProductVersion", "2.10.1.1"
EndDataSection
Windows 10 / Windows 7
PB Last Final / Last Beta Testing
Post Reply