簡體   English   中英

使用 vb.net 在 xml 中編輯標簽參數

[英]edit tag parameter in xml using vb.net

我有一個這種格式的xml:

    ?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <Products>
      <Categoria nome="etichetta">
        <riga1>val1</riga1>
        <riga2>val2</riga2>
        <riga3>val3</riga3>
      </Categoria>
      <Categoria nome="etichetta2">
        <riga1>val1</riga1>
        <riga2>val2</riga2>
        <riga3>val3</riga3>
      </Categoria>
..... and so on.....
    </Products>

所以我想改變值“etichetta”

Private Sub modifica_nome(nuovo_nome As String)
    Dim Percorso As String = "//Products/Categoria[@nome='" & Combo_Etichetta.SelectedItem & "']"
    Dim node = doc.SelectSingleNode(Percorso)
    node.Value = nuovo_nome 'here i get error. 
    doc.Save(file_etichette)
end sub

程序,將 xml 加載到組合框中:

doc.Load(file_etichette) 
        Combo_Etichetta.Items.AddRange(doc.DocumentElement.SelectNodes("Categoria").Cast(Of XmlNode).Select(Function(x) x.Attributes("nome").Value).ToArray)

然后我將數據加載到 combobox.selectedindexchanged 上的文本框

    Dim Percorso As String = "//Products/Categoria[@nome='" & Combo_Etichetta.SelectedItem & "']"
    
T_scatole_CODICE_1.Text = doc.DocumentElement.SelectSingleNode(Percorso & "/riga1").InnerText
T_scatole_QTA_1.Text = doc.DocumentElement.SelectSingleNode(Percorso & "/riga2").InnerText
T_scatole_POS_1.Text = doc.DocumentElement.SelectSingleNode(Percorso & "/riga3").InnerText

“@nome=”值鏈接到產品之后,我讓用戶選擇數據 trought 組合框,可視化數據並讓用戶在需要時從默認值進行修改,以打印標簽。 碰巧“@nome=”值需要更改為新模型產品,所以我需要更改它。

自己找到解決方案:錯誤是 node.vale 期望標簽“categoria”中有一些數據,但 nome="rtichetta" 不是標簽而是參數,因此必須使用 node.Attributes("nome").Value

Dim Percorso As String = "//Products/Categoria[@nome='" & Combo_Etichetta.SelectedItem & "']"
Dim node = doc.SelectSingleNode(Percorso)
node.Attributes("nome").Value = nuovo_nome
doc.Save(file_etichette)

創建類並使用 XML 序列化可以使處理 XML 變得更加容易——尤其是在您同時閱讀和更新 XML 的情況下。

首先,首先查看 XML 的結構。

- Products
    -Categoria
        -riga1
        -riga2
        -riga3

我們將為“產品”和“類別”創建一個類。

  • 產品:包含“類別”
  • ProductsCategoria:包含“Categoria”以及“riga1”、“riga2”、“riga3”的屬性

創建一個類(名稱:ProductsCategoria.vb)

ProductsCategoria.vb

Imports System.Xml.Serialization

<XmlType(TypeName:="Categoria")>
Public Class ProductsCategoria
    <XmlAttribute(AttributeName:="nome")>
    Public Property Nome As String

    <XmlElement(ElementName:="riga1")>
    Public Property riga1 As String

    <XmlElement(ElementName:="riga2")>
    Public Property riga2 As String

    <XmlElement(ElementName:="riga3")>
    Public Property riga3 As String

    Sub New()

    End Sub

    Sub New(nome As String, riga1 As String, riga2 As String, riga3 As String)
        'set values
        Me.Nome = nome
        Me.riga1 = riga1
        Me.riga2 = riga2
        Me.riga3 = riga3
    End Sub
End Class

OP 中沒有提供足夠的數據來了解“產品”是否可能包含多個“類別”,但從名稱“產品”是“產品”的復數形式來看,它表明它可能包含多個一個“類別”。 因此,我們將使用“類別”列表(ProductsCategoria)。 “riga1”、“riga2”和“riga3”都是唯一的名稱,因此它們不會使用列表。

創建一個類(名稱:Products.vb)

產品:

Imports System.Xml.Serialization


<XmlRoot(ElementName:="Products")>
Public Class Products

    <XmlElement(ElementName:="Categoria")>
    Public Categorias As New List(Of ProductsCategoria)

End Class

接下來,我們將編寫代碼以從文件中讀取 XML(反序列化)並將 XML 寫入文件(序列化)。

創建模塊(名稱:HelperXml.vb)

HelperXml.vb

Module HelperXml

    Public Function DeserializeXMLFileToObject(Of T)(xmlFilename As String) As T
        'usage
        'Dim myClass1 As Class1 = DeserializeXMLFileToObject(Class1)(xmlFilename)

        Dim rObject As T = CType(Nothing, T)

        Try
            If String.IsNullOrEmpty(xmlFilename) Then
                Return rObject
            End If

            Using xmlStream As System.IO.StreamReader = New System.IO.StreamReader(xmlFilename)
                'create new instance
                Dim serializer As System.Xml.Serialization.XmlSerializer = New System.Xml.Serialization.XmlSerializer(GetType(T))

                'read XML from file
                rObject = CType(serializer.Deserialize(xmlStream), T)
            End Using
        Catch ex As Exception
            Debug.WriteLine("Error (DeserializeXMLFileToObject) - " & ex.Message)
            Throw ex
        End Try

        Return rObject
    End Function

    Public Sub SerializeObjectToXMLFile(obj As Object, xmlFilename As String)
        'Usage:
        'Dim myClass1 As Class1 = New Class1()
        'SerializeObjectToXMLFile(myClass1, xmlFilename)

        Try
            If String.IsNullOrEmpty(xmlFilename) Then
                Return
            End If

            Dim settings As System.Xml.XmlWriterSettings = New System.Xml.XmlWriterSettings()
            settings.Encoding = System.Text.Encoding.UTF8
            settings.OmitXmlDeclaration = False
            settings.Indent = True

            Using xmlWriter As System.Xml.XmlWriter = System.Xml.XmlWriter.Create(xmlFilename, settings)
                'specify namespaces
                Dim ns As System.Xml.Serialization.XmlSerializerNamespaces = New System.Xml.Serialization.XmlSerializerNamespaces()
                ns.Add(String.Empty, "urn:none")

                xmlWriter.WriteProcessingInstruction("xml", "version=""1.0"" encoding=""UTF-8"" standalone=""yes""")

                'create new instance
                Dim serializer As System.Xml.Serialization.XmlSerializer = New System.Xml.Serialization.XmlSerializer(obj.GetType())

                'write XML to file
                serializer.Serialize(xmlWriter, obj, ns)

            End Using

        Catch ex As Exception
            Debug.WriteLine("Error (SerializeObjectToXMLFile) - " & ex.Message)
            Throw ex
        End Try
    End Sub
End Module

用法

Private prods As New Products
Private xmlFilename As String = New String("C:\Temp\test_products.xml")
                   ...

Private Sub ChangeName(index As Integer, name As String)
    If prods IsNot Nothing AndAlso prods.Categorias.Count > 0 AndAlso index >= 0 AndAlso index < prods.Categorias.Count Then
        prods.Categorias(index).Nome = name

        'Write to file
        SerializeObjectToXMLFile(prods, xmlFilename)
    End If
End Sub

Private Sub ReadXmlFromFile()
    prods = HelperXml.DeserializeXMLFileToObject(Of Products)(xmlFilename)
End Sub

Private Sub WriteXmlToFile()
    prods.Categorias.Add(New ProductsCategoria("etichetta", "val1", "val2", "val3"))
    SerializeObjectToXMLFile(prods, xmlFilename)
End Sub

資源

Dim Percorso As String = "//Products/Categoria[@nome='" & Combo_Etichetta.SelectedItem & "']"
Dim node = doc.SelectSingleNode(Percorso)
node.Attributes("nome").Value = nuovo_nome

可以縮短為

Dim Percorso As String = "//Products/Categoria/@nome[. = '" & Combo_Etichetta.SelectedItem & "']"
Dim node = doc.SelectSingleNode(Percorso)
node.Value = nuovo_nome

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM