I'm using VB.Net and want to read specific values from an xml file (it's an xmp file from DarkTable). I'm wanting to read the notes and tag values (when they exist) indicated below as '*** THIS VALUE ***'.
I can usually fumble my way through reading xml values but the colons and namespaces are an extra challenge.
Any help is appreciated. Thank you.
What I have so far is:
Private Function GetHTMLForTagsAndNotes(ByVal ImageFullPath As String) As String
Dim strXMPFilename As String = ImageFullPath & ".xmp"
Dim doc As New Xml.XmlDocument()
Dim strNote As String
Dim lstTags As New List(Of String)
Dim strReturnHTML As String = ""
doc.Load(strXMPFilename)
Try
'Read xml notes and tags
'(START: NEED HELP HERE PLEASE)
'If an acdsee:notes value exists
strNote = "*** THIS VALUE ***"
'For each tag that exists
lstTags.Add("*** THIS VALUE ***")
'(END: NEED HELP HERE PLEASE)
Catch ex As Exception
MsgBox(ex.Message)
End Try
'Format the tags and/or note as HTML and return
Return strReturnHTML
End Function
The XML format is:
<?xml version="1.0" encoding="UTF-8"?>
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 4.4.0-Exiv2">
<rdf:RDF xmlns:rdf="URL//www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:about=""
xmlns:exif="URL//ns.adobe.com/exif/1.0/"
xmlns:xmp="URL//ns.adobe.com/xap/1.0/"
xmlns:xmpMM="URL//ns.adobe.com/xap/1.0/mm/"
xmlns:darktable="URL//darktable.sf.net/"
xmlns:acdsee="URL//ns.acdsee.com/iptc/1.0/"
xmlns:dc="URL//purl.org/dc/elements/1.1/"
xmlns:lr="URL//ns.adobe.com/lightroom/1.0/"
exif:DateTimeOriginal=""
xmp:Rating="1"
xmpMM:DerivedFrom="SCAN_20230401_0392.jpg"
darktable:import_timestamp="63815945870187001"
darktable:change_timestamp="-1"
darktable:export_timestamp="63841000148835795"
darktable:print_timestamp="-1"
darktable:xmp_version="5"
darktable:raw_params="0"
darktable:auto_presets_applied="1"
darktable:history_end="4"
darktable:iop_order_version="2"
darktable:history_basic_hash="c80077d119ae746632f44df3493dfd64"
darktable:history_current_hash="c80077d119ae746632f44df3493dfd64"
acdsee:notes="*** THIS VALUE ***">
<darktable:masks_history>
<rdf:Seq/>
</darktable:masks_history>
<darktable:history>
<rdf:Seq>
<rdf:li
darktable:num="0"
darktable:operation="colorin"
darktable:enabled="1"
darktable:modversion="7"
darktable:params="gz48eJxjZBgFowABWAbaAaNgwAEAEDgABg=="
darktable:multi_name=""
darktable:multi_priority="0"
darktable:blendop_version="11"
darktable:blendop_params="gz14eJxjYIAACQYYOOHEgAZY0QVwggZ7CB6pfNoAAE8gGQg="/>
</rdf:Seq>
</darktable:history>
<dc:subject>
<rdf:Bag>
<rdf:li>*** THIS VALUE ***</rdf:li>
<rdf:li>*** THIS VALUE ***</rdf:li>
<rdf:li>*** THIS VALUE ***</rdf:li>
<rdf:li>*** THIS VALUE ***</rdf:li>
</rdf:Bag>
</dc:subject>
<lr:hierarchicalSubject>
<rdf:Bag>
<rdf:li>*** THIS VALUE ***</rdf:li>
<rdf:li>*** THIS VALUE ***</rdf:li>
<rdf:li>*** THIS VALUE ***</rdf:li>
<rdf:li>*** THIS VALUE ***</rdf:li>
</rdf:Bag>
</lr:hierarchicalSubject>
</rdf:Description>
</rdf:RDF>
</x:xmpmeta>
Please try the following solution based on LINQ to XML API. It is available in the .Net Framework since 2007.
Notable points:
<rdf:li>
XML elements that have <rdf:Bag>
XML element as a parent.VB.NET
Sub Main
Const FILENAME As String = "e:\Temp\JakeSmith.xml"
Dim xdoc As XDocument = XDocument.Load(FILENAME)
Dim ns As XNamespace = "URL//www.w3.org/1999/02/22-rdf-syntax-ns#"
Dim ns1 As XNamespace = "URL//ns.acdsee.com/iptc/1.0/"
Dim listOfString As List(Of String) = xdoc.Descendants(ns + "li") _
.Where(Function(x) x.Parent.Name.LocalName = "Bag") _
.[Select](Function(x) x.Value).ToList()
Console.Write(listOfString)
Dim notes As String = xdoc.Descendants(ns + "Description") _
.Attributes(ns1 + "notes").FirstOrDefault()?.Value
Console.Write(notes)
End Sub
Output
List (8 items) |
---|
*** THIS VALUE *** |
*** THIS VALUE *** |
*** THIS VALUE *** |
*** THIS VALUE *** |
*** THIS VALUE *** |
*** THIS VALUE *** |
*** THIS VALUE *** |
*** THIS VALUE *** |