У меня есть XML-файл, как показано ниже;

<ZPPORDER01>
  <IDOC BEGIN="1">
    <EDI_DC40 SEGMENT="1">
      <TABNAM>EDI_DC40</TABNAM>
      <MANDT>100</MANDT>
      <DOCNUM>0000000000000001</DOCNUM>
    </EDI_DC40>
    <Z1PPORDITEM SEGMENT="1">
      <AUFNR>000000000123</AUFNR>
      <POSNR>0001</POSNR>
      <Z1PPORDOPER SEGMENT="1">
        <VORNR>0010</VORNR>
        <ARBPL>PIGME</ARBPL>
        <Z1PPORDCOMP SEGMENT="1">
          <POSNR>0100</POSNR>
          <CPARAM>RV ;</CPARAM>
        </Z1PPORDCOMP>
        <Z1PPORDCOMP SEGMENT="1">
          <POSNR>0200</POSNR>
          <CPARAM>PLT;</CPARAM>
        </Z1PPORDCOMP>
     </Z1PPORDOPER>
    </Z1PPORDITEM>
  </IDOC>
</ZPPORDER01>

Я хотел бы прочитать PosNR и CPARAM для каждого узла <Z1PPORDCOMP SEGMENT="1">. Как видно, существует несколько узлов с одинаковым именем узла (Z1PPORDCOMP SEGMENT = "1" и одинаковыми дочерними именами (POSNR, CPARAM).

Я хотел бы прочитать весь внутренний текст ребенка и назначить 4 различных строки в скане.

Я написал сценарий ... Я определил 4 строки для чтения данных для каждого ребенка. Я могу прочитать значение из первых двух, но я не знаю, как получить данные из следующих дочерних значений.

Я искал Xml.XPath используется, но я не мог понять, как использовать его в этом случае.


dim doc as System.Xml.XmlDocument;
dim node as System.Xml.XmlNode;
doc = new System.Xml.XmlDocument;
doc.Load("\\mypc\ShareOn\INPUT\Test.xml");

dim PosNR0100 as string ;
dim PosNR0100_CPARAM as string ;
dim PosNR0200 as string ;
dimPosNR0200_CPARAM as string ;

PosNR0100       = doc.SelectSingleNode("/ZPPORDER01/IDOC [@BEGIN='1']/Z1PPORDITEM [@SEGMENT='1']/Z1PPORDOPER [@SEGMENT='1']/Z1PPORDCOMP [@SEGMENT='1']/POSNR").InnerText;

PosNR0100_CPARAM    = doc.SelectSingleNode("/ZPPORDER01/IDOC [@BEGIN='1']/Z1PPORDITEM [@SEGMENT='1']/Z1PPORDOPER [@SEGMENT='1']/Z1PPORDCOMP [@SEGMENT='1']/CPARAM").InnerText;
PosNR0200       = ?
PosNR0200_CPARAM    = ?
-2
Mahmut 18 Дек 2019 в 20:42

2 ответа

Использовать XML-сериализацию

Создать классы для представления ваших данных

Imports System.Xml.Serialization
Imports System.IO
Public Class ZPPORDER01
    Public Property IDOC As IDOC
End Class
Public Class IDOC
    Public Property EDI_DC40 As EDI_DC40
    Public Property Z1PPORDITEM As Z1PPORDITEM
End Class

Public Class EDI_DC40
    Public Property TABNAM As String
    Public Property MANDT As String
    Public Property DOCNUM As String
End Class
Public Class Z1PPORDITEM
    <XmlAttribute>
    Public Property SEGMENT As Integer
    Public Property AUFNR As String
    Public Property POSNR As String
    Public Property Z1PPORDOPER As Z1PPORDOPER
End Class
Public Class Z1PPORDOPER
    <XmlAttribute>
    Public Property SEGMENT As Integer
    Public Property VORNR As String
    Public Property ARBPL As String
    <XmlElement("Z1PPORDCOMP")>
    Public Property Z1PPORDCOMPs As List(Of Z1PPORDCOMP)
End Class
Public Class Z1PPORDCOMP
    <XmlAttribute>
    Public Property SEGMENT As Integer
    Public Property POSNR As String
    Public Property CPARAM As String
End Class

Затем десериализовать

Dim s As New XmlSerializer(GetType(ZPPORDER01))
Dim z As ZPPORDER01
Using sr As New StreamReader("filename.xml")
    z = DirectCast(s.Deserialize(sr), ZPPORDER01)
End Using
For Each comp In z.IDOC.Z1PPORDITEM.Z1PPORDOPER.Z1PPORDCOMPs
    MessageBox.Show($"POSNR: {comp.POSNR}, CPARAM: {comp.CPARAM}")
Next
1
djv 18 Дек 2019 в 18:56

Вы можете использовать запросы XPath, как это:

Imports System.Xml

Module Module1

    Sub Main()
        Dim src = "C:\temp\ZPPORDER.xml"
        Dim doc As New XmlDocument
        doc.Load(src)

        Dim posnrs As New List(Of String)
        Dim cparams As New List(Of String)

        Dim z1ppordcomps = doc.SelectNodes("//Z1PPORDCOMP[@SEGMENT='1']")
        For Each n As XmlNode In z1ppordcomps
            Dim posnr = n.SelectSingleNode("POSNR")
            Dim cparam = n.SelectSingleNode("CPARAM")
            If posnr IsNot Nothing AndAlso cparam IsNot Nothing Then
                posnrs.Add(posnr.InnerText)
                cparams.Add(cparam.InnerText)
            End If
        Next

        Console.WriteLine("POSNR: " & String.Join(",", posnrs))
        Console.WriteLine("CPARAM: " & String.Join(", ", cparams))

        Console.ReadLine()

    End Sub

End Module

Выходы:

POSNR: 0100,0200
CPARAM: RV;, PLT;

Вы можете получить к ним доступ по отдельности с помощью posnrs(0), posnrs(1), cparams(0) и cparams(1).

0
Andrew Morton 18 Дек 2019 в 19:03