Page 1 of 1
Can the XML lib handle this?
Posted: Sun Mar 14, 2021 3:22 am
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
Re: Can the XML lib handle this?
Posted: Sun Mar 14, 2021 8:43 am
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
Re: Can the XML lib handle this?
Posted: Sun Mar 14, 2021 2:58 pm
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>
Re: Can the XML lib handle this?
Posted: Sun Mar 14, 2021 4:10 pm
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 ...

Re: Can the XML lib handle this?
Posted: Sun Mar 14, 2021 4:46 pm
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
Re: Can the XML lib handle this?
Posted: Sun Mar 14, 2021 8:13 pm
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