admin管理员组

文章数量:1123260

I have an Xml document with the following excerpt:

<Transport>
    <TransportID TransportIdentifierType="Registration">ABC123A</<TransportID >
    <TransportID TransportIdentifierType="Driver">Smith</<TransportID >
    <TransportID TransportIdentifierType="Trailer">TR1029</<TransportID >
</Transport>

Using CreateNavigator, I can get to the tag <Transport>, and using a Do/While loop with .MoveToNext, I can read each value. e.g.:

Do
    If nav.Name() = "TransportID " Then
        Console.WriteLine(nav.Name & ": " & nav.Value)
    End If
Loop While nav.MoveToNext

which outputs:

TransportID: ABC123A

TransportID: Smith

TransportID: TR1029

How do I get the value for only TransportIdentifierType="Registration" without assuming its the first in the list.

If tried a bunch of stuff under "nav.", so:

docNav = New XPathDocument("document.xml")
nav = docNav.CreateNavigator

and then nav.value, etc but I can't return the "TransportIdentifierType" value inorder to check whether its the one I want.

I feel the answer is going to be using:

Console.WriteLine(nav.SelectSingleNode("[@TransportIdentifierType='Registration']").Value)

but I'm stuck. I don't really want to always assume that its going to X value in a list of returned values. Also tried: nav.GetAttribute()

nav.OuterXml returns the whole line which is useable

I have an Xml document with the following excerpt:

<Transport>
    <TransportID TransportIdentifierType="Registration">ABC123A</<TransportID >
    <TransportID TransportIdentifierType="Driver">Smith</<TransportID >
    <TransportID TransportIdentifierType="Trailer">TR1029</<TransportID >
</Transport>

Using CreateNavigator, I can get to the tag <Transport>, and using a Do/While loop with .MoveToNext, I can read each value. e.g.:

Do
    If nav.Name() = "TransportID " Then
        Console.WriteLine(nav.Name & ": " & nav.Value)
    End If
Loop While nav.MoveToNext

which outputs:

TransportID: ABC123A

TransportID: Smith

TransportID: TR1029

How do I get the value for only TransportIdentifierType="Registration" without assuming its the first in the list.

If tried a bunch of stuff under "nav.", so:

docNav = New XPathDocument("document.xml")
nav = docNav.CreateNavigator

and then nav.value, etc but I can't return the "TransportIdentifierType" value inorder to check whether its the one I want.

I feel the answer is going to be using:

Console.WriteLine(nav.SelectSingleNode("[@TransportIdentifierType='Registration']").Value)

but I'm stuck. I don't really want to always assume that its going to X value in a list of returned values. Also tried: nav.GetAttribute()

nav.OuterXml returns the whole line which is useable

Share Improve this question edited 9 hours ago PutUponDave asked 10 hours ago PutUponDavePutUponDave 12 bronze badges New contributor PutUponDave is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 1
  • The following may be of interest: stackoverflow.com/a/73640395/10024425 – It all makes cents Commented 9 hours ago
Add a comment  | 

2 Answers 2

Reset to default 0

This little test...

Dim xml As XElement =
    <root>
        <Transport>
            <TransportID TransportIdentifierType="Registration">ABC123A</TransportID>
            <TransportID TransportIdentifierType="Driver">Smith</TransportID>
            <TransportID TransportIdentifierType="Trailer">TR1029</TransportID>
        </Transport>
    </root>
Dim transport = xml.<Transport>.First()
Dim transportIds = transport.<TransportID>  'IEnumerable(Of XElement)
For Each transportId In transportIds
    Console.WriteLine($"{transportId.@TransportIdentifierType} = {transportId.Value}")
Next

... prints:

Registration = ABC123A
Driver = Smith
Trailer = TR1029

And this ...

Dim registration As String = transport.<TransportID>.
    First(Function(x) x.@TransportIdentifierType = "Registration").
    Value
Console.WriteLine(registration)

...prints

ABC123A

Note that First() does not mean that it has to be the first item, it means that it will return the first one it finds. It will throw an exception if none is found. You can use FirstOrDefault() if you don't want to throw an exception. It will return Nothing instead.

You would have to open the file as XDocument with

Dim doc = XDocument.Load("document.xml")

See also:

  • XML in Visual Basic
  • Lambda Expressions (Visual Basic)

Use Xml Serialization

Make a model for your file

<XmlRoot>
Public Class Transport
    <XmlElement("TransportID")> Public Property TransportIDs As List(Of TransportID)
End Class

Public Class TransportID
    <XmlAttribute> Public Property TransportIdentifierType As String
    <XmlText> Public Property Value As String
End Class

Deserialize and find the match

Dim t As Transport
Dim s As New XmlSerializer(GetType(Transport))
Using fs As New FileStream("filename.xml", FileMode.Open)
    t = s.Deserialize(fs)
End Using

Console.WriteLine(t.TransportIDs?.First(Function(ti) ti.TransportIdentifierType = "Registration")?.Value)

If you need, edit and serialize (write) back to the file

t.TransportIDs.First(Function(ti) ti.TransportIdentifierType = "Registration").Value = "Modified"

Using sw As New StreamWriter("filename.xml")
    s.Serialize(sw, t)
End Using

本文标签: xmlHow get specific value from an attribute or element typeStack Overflow