I’m missing something really basic in handling XMLs. I’ve been through the Xojo XML documentation many times and still can’t seem to apply the baseball team examples to what I need to do - just as one example, when to use XMLElement instead of XMLNode.
I have an XML document that contains a number of <asset>
elements, or should I call them nodes?
Here’s an assetNode:
<asset id="r2" name="PBSNH190411CL" uid="37CBD7BC415034F81EAC4873F797777A" src="file:///Volumes/EDIT01_SSDRAID01/Test%20Media/PBSNH190411CL.mp4" start="0s" duration="11286275/30000s" hasVideo="1" format="r1" hasAudio="1" audioSources="1" audioChannels="2" audioRate="48000"><metadata><md key="com.apple.proapps.studio.rawToLogConversion" value="0"/><md key="com.apple.proapps.spotlight.kMDItemCodecs"><array><string>AAC</string><string>AVC</string></array></md><md key="com.apple.proapps.mio.ingestDate" value="2020-07-24 15:58:14 -0400"/></metadata></asset>
I need the value in “id” which is “r2”. But when I try the following code nothing is returned:
dim assetID as string = assetNode.GetAttribute("id")
What am I doing wrong?
More code please.
Are you sure assetNode points to that XML?
e.g. is that the xml from assetNode.toString?
Thanks, Christian.
Yes, I pasted the above code from assetNode.toString in the Debugger.
AssetClip is passed to the code below by another function. ResourceNode was found using XQL on the XML document in use.
Everything is reading and writing correctly to assetClip (the passed node) but nothing is reading from assetNode.
Once the code finds a assetNode/assetClip match the code updates assetClip’s “ref” attribute. Then assetNode is cloned, modified a little more and then appended to ResourceNode.
dim assetNode as XmlNode
dim resourceAssetList as XmlNodeList = ResourceNode.xql("asset")
for i as integer = 0 to resourceAssetList.Length - 1 'find the clips <asset> in the ResourceNode
assetNode = resourceAssetList.Item(i)
dim assetID as string = assetNode.GetAttribute("id") 'get the assetNode's "id" value
dim assetClipRef as string = assetClip.GetAttribute("ref") 'assetClip's "ref" value
if assetID = assetClipRef then 'if assetNode's "id" and assetClip's "ref" match
dim assetClipName as string = assetClip.GetAttribute("name") 'get the <asset-clip> name
ConsAssetClipCount = ConsAssetClipCount + 1 'increment the consolidated clip counter, ConsAssetClipCount
dim newAssetID as string = assetID + "." + cstr(ConsAssetClipCount)
assetClip.SetAttribute("ref", newAssetID) 'set the <asset-clip> "ref" value to its new <asset> ID value
assetClip.SetAttribute("name", assetClipName + "." + cstr(ConsAssetClipCount)) 'set the <asset-clip>'s new consolidated name
dim newAssetNode as XmlNode = assetNode.Clone(true) 'clone the <asset> node
newAssetNode.SetAttribute("id", newAssetID) 'give the new <asset> node its new "id" value
newAssetNode.SetAttribute("start", assetClip.GetAttribute("start"))
newAssetNode.SetAttribute("duration", assetClip.GetAttribute("duration"))
newAssetNode.RemoveAttribute("bookmark") 'remove the old bookmark from the new <asset> node
for x as integer = 0 to newAssetNode.ChildCount - 1 'find the old bookmark data in the new <asset> node
dim child as XmlNode = newAssetNode.Child(x)
if child.Name = "bookmark" then newAssetNode.RemoveChild(child) 'delete the old <bookmark> from the new <asset> node
exit
next x
ResourceNode.AppendChild(newAssetNode) ' append the new <asset> node to "ResourceNode"
exit
end if
next i
Thanks, Christian, you had the answer. I had cloned part of the original XML earlier and my code was still pointing to the original. All is working as expected now. Many Thanks!
Great. Sometimes looking into the problem after a break helps.