基于节点属性值覆盖元素值

时间:2013-10-15 13:43:56

标签: xml vb.net visual-studio-2010 linq-to-xml

我的xml文档结构如下:

<Root>
  <Word ID="23">
    <Type>auxiliary</Type>
    <English></English>
    <Thai></Thai>
    <Meaning></Meaning>
    <Audio>Dictionary Resources\Sound Files\23.wma</Audio>
    <Picture>Dictionary Resources\Picture Files\23.jpg</Picture>
    <Transliteration></Transliteration>
    <Timestamp />
  </Word>
...
</Root>

每个节点都有一个唯一的属性(ID)。我想做的是,使用属性的用户输入,在这种情况下,int值23,是修改时间戳的.Value。

在伪代码中,像这样:

    Sub Timestamp(ByVal IDChosen As String)
    Dim Dictionary As XDocument = XDocument.Load("Dictionary Resources\Dictionary.xml")
    Dictionary.Root.Elements("Word").Atrribute"ID"(IDChosen).Value = DateTime.Now
    Dictionary.Save("Dictionary Resources\Dictionary.xml")
    End Sub

1 个答案:

答案 0 :(得分:1)

有多种方法可以做到这一点。您可以将<>@语法与XDocument对象一起使用,以深入查看所需的元素,如下所示:

Sub Timestamp(idChosen As String)
    Dim doc As XDocument = XDocument.Load("Dictionary Resources\Dictionary.xml")
    Dim word As XElement = doc.<Root>.<Word>.FirstOrDefault(Function(x) x.@ID = idChosen)
    If word IsNot Nothing Then
        word.<Timestamp>.First().SetValue(Date.Now)
        doc.Save("Dictionary Resources\Dictionary.xml")
    End If
End Sub

或者您可以使用XPath来选择元素,如下所示:

Sub Timestamp(idChosen As String)
    Dim doc As XDocument = XDocument.Load("Dictionary Resources\Dictionary.xml")
    Dim timeStamp As XElement = doc.XPathSelectElement("/Root/Word[@ID='" & idChosen & "']/Timestamp")
    If timeStamp IsNot Nothing Then
        timeStamp.SetValue(Date.Now)
        doc.Save("Dictionary Resources\Dictionary.xml")
    End If
End Sub

或者,您可以使用查询语法来选择元素,如下所示:

Sub Timestamp(idChosen As String)
    Dim doc As XDocument = XDocument.Load("Dictionary Resources\Dictionary.xml")
    Dim t As XElement = _
        (
        From word In doc.<Root>.<Word> 
        Where word.@ID = idChosen 
        Select word.<Timestamp>.FirstOrDefault()
        ).FirstOrDefault()
    If t IsNot Nothing Then
        t.SetValue(Date.Now)
        doc.Save("Dictionary Resources\Dictionary.xml")
    End If
End Sub

或者,如果您想在不使用<>@语法的情况下使用查询语法,您可以这样做:

Sub Timestamp(idChosen As String)
    Dim doc As XDocument = XDocument.Load("Dictionary Resources\Dictionary.xml")
    Dim t As XElement = _
        (
        From word In doc.Root.Elements("Word") 
        Where word.Attributes("ID").Any(Function(x) x.Value = idChosen) 
        Select word.Element("Timestamp")
        ).FirstOrDefault()
    If t IsNot Nothing Then
        t.SetValue(Date.Now)
        doc.Save("Dictionary Resources\Dictionary.xml")
    End If
End Sub

或者,如果您不关心实际的XML文档结构,并且您只想找到具有该ID的第一个Word元素,无论它位于文档树中的哪个位置,您都可以选择像这样的元素:

Dim word As XElement = doc...<Word>.FirstOrDefault(Function(x) x.@ID = idChosen)

或者:

Dim timeStamp As XElement = doc.XPathSelectElement("//Word[@ID='" & idChosen & "']/Timestamp")

或者:

Dim t As XElement = _
    (
    From word In doc.Descendants("Word") 
    Where word.@ID = idChosen 
    Select word.<Timestamp>.FirstOrDefault()
    ).FirstOrDefault()

或者:

Dim t As XElement = _
    (
    From word In doc.Descendants("Word") 
    Where word.Attributes("ID").Any(Function(x) x.Value = idChosen) 
    Select word.Element("Timestamp")
    ).FirstOrDefault()

就个人而言,我建议使用选择节点的XPath方法,因为它简短,易读,而且它使用的是行业标准的查询语言,而不是微软专有的LINQ技术,但这只是我:)< / p>

相关问题