簡體   English   中英

如何使用C#在xml文件的子節點下讀取具有相同名稱的多個標簽?

[英]How to read multiple tags with same name under child node in a xml file using c#?

對於下面的xml,我想讀取所有行節點的值,如您所見,在subcategory標簽下有多個行標簽,因此對於特定的subcategory(假設SubCategory ID =“ Standard”),我想獲取所有行標簽? 如何使用C#做到這一點?

<DPS>
  <Category ID="Handsets">
    <Device ID="Samsung">
      <Contract ID="twoFour">
        <Tariff ID="Standard4G">
          <SubCategory ID="Standard">
            <Row>
              <Minutes>"Minutes":"999999"</Minutes>
              <Texts>"Texts":"99999"</Texts>
              <Data>"Data":"10000"</Data>
              <Content>"Content":"No"</Content>
              <Roaming>"Roaming":"Y + 2000"</Roaming>
              <Monthly>"Monthly":"38"</Monthly>
              <Upfront>"Upfront":0"</Upfront>
            </Row>
            <Row>
              <Minutes>Minutes:999</Minutes>
              <Texts>Texts:99994569</Texts>
              <Data>Data:100</Data>
              <Content>Content:No</Content>
              <Roaming>Roaming:Y + 2000</Roaming>
              <Monthly>Monthly:398</Monthly>
              <Upfront>Upfront:0</Upfront>
            </Row>
            <Row>
              <Minutes>Minutes:99</Minutes>
              <Texts>Texts:92569</Texts>
              <Data>Data:10</Data>
              <Content>Content:No</Content>
              <Roaming>Roaming:Y + 2000</Roaming>
              <Monthly>Monthly:38</Monthly>
              <Upfront>Upfront:0</Upfront>
            </Row>
          </SubCategory>
          <SubCategory ID="RedValue">
            <Row>
              <Minutes>"Minutes":"999999"</Minutes>
              <Texts>"Texts":"99999"</Texts>
              <Data>"Data":"10000"</Data>
              <Content>"Content":"No"</Content>
              <Roaming>"Roaming":"Y + 2000"</Roaming>
              <Monthly>"Monthly":"38"</Monthly>
              <Upfront>"Upfront":0"</Upfront>
            </Row>
            <Row>
              <Minutes>Minutes:999</Minutes>
              <Texts>Texts:99994569</Texts>
              <Data>Data:100</Data>
              <Content>Content:No</Content>
              <Roaming>Roaming:Y + 2000</Roaming>
              <Monthly>Monthly:398</Monthly>
              <Upfront>Upfront:0</Upfront>
            </Row>
            <Row>
              <Minutes>Minutes:99</Minutes>
              <Texts>Texts:92569</Texts>
              <Data>Data:10</Data>
              <Content>Content:No</Content>
              <Roaming>Roaming:Y + 2000</Roaming>
              <Monthly>Monthly:38</Monthly>
              <Upfront>Upfront:0</Upfront>
            </Row>
          </SubCategory>
        </Tariff>
      </Contract>
    </Device>
  </Category>
</DPS>

首先,將XML加載到XDocument中。

var xdoc = XDocument.Parse(xml); // Or XDocument.Load(pathToXmlFile), etc....

然后,您可以在所有SubCategory元素中查詢ID為“ Standard”的一個,最后要求其所有子元素(行)。

var rows = xdoc.Descendants("SubCategory")
  .Where(sc => sc.Attribute("ID").Value == "Standard")
  .Elements();

編輯 :要從上述XML中獲取實際值,這是一種方法。

我做了一個內聯函數,以按名稱從行中獲取給定元素,並處理從中刪除不需要的字符。

Func<XElement, string, string> getElementValue = (XElement row, string name)
    => row.Element(name).Value
        .Split(':').Last() // Take only the right side of the colons
        .Trim('"'); // Remove the double quotes, if any

然后,我們可以使用它來獲取每一行的所有預期屬性:

var rowData = rows.Select(x => new {
    Minutes = getElementValue(x, "Minutes"),
    Texts = getElementValue(x, "Texts"),
    Data = getElementValue(x, "Data"),
    Content = getElementValue(x, "Content"),
    Roaming = getElementValue(x, "Roaming"),
    Monthly = getElementValue(x, "Monthly"),
    Upfront = getElementValue(x, "Upfront")
});

為了實際使用,如果您尚未定義類,則可能要創建一個類,該類具有諸如Minutes,Texts等的屬性,然后將該類名放在要選擇行的new關鍵字之后。

編輯2 :將每個元素中的多余文本確認為“鍵入錯誤”,您可以完全跳過內聯函數,並將rowData選擇簡化為:

var rowData = rows.Select(x => new {
    Minutes = x.Element("Minutes").Value,
    Texts = x.Element("Texts").Value,
    Data = x.Element("Data").Value,
    Content = x.Element("Content").Value,
    Roaming = x.Element("Roaming").Value,
    Monthly = x.Element("Monthly").Value,
    Upfront = x.Element("Upfront").Value
});

無法使用我可以訪問的轉換器將此VB代碼轉換為C#。 我知道XML文字在C#中沒有對應的文字,但是除了具有一些測試數據外,不需要任何其他內容。

由於XML看起來結構良好,因此我創建了一系列模擬數據的類。 它們只是一個起點,因為我不知道數據的來龍去脈。

讓我們從查看Standard的每一行開始。 添加了調試以幫助可視化。

    Dim myDPS As New DPS(xe)
    myDPS.Category.Device.Tariff.SubCategory.GetOnePart("Standard")
    Debug.WriteLine(myDPS.Category.Device.Tariff.SubCategory.OnePart.ToString)
    For Each el As XElement In myDPS.Category.Device.Tariff.SubCategory.Row.OnePart.Elements
        Debug.WriteLine(el.ToString)
    Next

這是課程。

Public Class DPS : Inherits DPSBaseClass

    Public Category As DPSCategory

    Public Sub New(path As String)
        MyBase.New(XElement.Load(path))
    End Sub

    Public Sub New(element As XElement)
        MyBase.New(element)
        If Me.OnePart IsNot Nothing Then
            Me.Category = New DPSCategory(Me.OnePart)
        End If
    End Sub
End Class

Public Class DPSCategory : Inherits DPSBaseClass

    Public Device As DPSDevice

    Public Sub New(element As XElement)
        MyBase.New(element)
        If Me.OnePart IsNot Nothing Then
            Me.Device = New DPSDevice(Me.OnePart)
        End If
    End Sub
End Class

Public Class DPSDevice : Inherits DPSBaseClass

    Public Tariff As DPSTariff

    Public Sub New(element As XElement)
        MyBase.New(element)
        If Me.OnePart IsNot Nothing Then
            Me.Tariff = New DPSTariff(Me.OnePart)
        End If
    End Sub
End Class

Public Class DPSTariff : Inherits DPSBaseClass

    Public SubCategory As DPSSubCategory

    Public Sub New(element As XElement)
        MyBase.New(element)
        If Me.OnePart IsNot Nothing Then
            Me.SubCategory = New DPSSubCategory(Me.OnePart)
        End If
    End Sub
End Class

Public Class DPSSubCategory : Inherits DPSBaseClass

    Public Row As DPSSubCategoryRow

    Public Sub New(element As XElement)
        MyBase.New(element)
        If Me.OnePart IsNot Nothing Then
            Me.Row = New DPSSubCategoryRow(Me.OnePart)
        End If
    End Sub
End Class

Public Class DPSSubCategoryRow : Inherits DPSBaseClass

    Public Sub New(element As XElement)
        MyBase.New(element)
    End Sub
End Class

Public MustInherit Class DPSBaseClass

    Private TheData As XElement
    Private DataParts As New List(Of XElement)
    Public OnePart As XElement

    Public Sub New(path As String)
        Me.New(XElement.Load(path))
    End Sub

    Public Sub New(element As XElement)
        Me.TheData = element
        Me.GetDataParts()
    End Sub

    Public Sub GetDataParts()
        Me.DataParts = (From el In Me.TheData.Elements Select el).ToList
        Me.GetOnePart("")
    End Sub

    Public Sub GetOnePart(ID As String)
        If Me.DataParts.Count > 0 Then
            If ID <> "" Then
                Me.OnePart = (From el In Me.DataParts Where el.@ID = ID Select el Take 1).FirstOrDefault
            Else
                Me.OnePart = Me.DataParts.FirstOrDefault
            End If
        End If
    End Sub

End Class

這是用來測試的討厭的XML文字

    Dim xe As XElement = <DPS>
                             <Category ID="Handsets">
                                 <Device ID="Samsung">
                                     <Contract ID="twoFour">
                                         <Tariff ID="Standard4G">
                                             <SubCategory ID="Standard">
                                                 <Row>
                                                     <Minutes>"Minutes":"999999"</Minutes>
                                                     <Texts>"Texts":"99999"</Texts>
                                                     <Data>"Data":"10000"</Data>
                                                     <Content>"Content":"No"</Content>
                                                     <Roaming>"Roaming":"Y + 2000"</Roaming>
                                                     <Monthly>"Monthly":"38"</Monthly>
                                                     <Upfront>"Upfront":0"</Upfront>
                                                 </Row>
                                                 <Row>
                                                     <Minutes>Minutes:999</Minutes>
                                                     <Texts>Texts:99994569</Texts>
                                                     <Data>Data:100</Data>
                                                     <Content>Content:No</Content>
                                                     <Roaming>Roaming:Y + 2000</Roaming>
                                                     <Monthly>Monthly:398</Monthly>
                                                     <Upfront>Upfront:0</Upfront>
                                                 </Row>
                                                 <Row>
                                                     <Minutes>Minutes:99</Minutes>
                                                     <Texts>Texts:92569</Texts>
                                                     <Data>Data:10</Data>
                                                     <Content>Content:No</Content>
                                                     <Roaming>Roaming:Y + 2000</Roaming>
                                                     <Monthly>Monthly:38</Monthly>
                                                     <Upfront>Upfront:0</Upfront>
                                                 </Row>
                                             </SubCategory>
                                             <SubCategory ID="RedValue">
                                                 <Row>
                                                     <Minutes>"Minutes":"999999"</Minutes>
                                                     <Texts>"Texts":"99999"</Texts>
                                                     <Data>"Data":"10000"</Data>
                                                     <Content>"Content":"No"</Content>
                                                     <Roaming>"Roaming":"Y + 2000"</Roaming>
                                                     <Monthly>"Monthly":"38"</Monthly>
                                                     <Upfront>"Upfront":0"</Upfront>
                                                 </Row>
                                                 <Row>
                                                     <Minutes>Minutes:999</Minutes>
                                                     <Texts>Texts:99994569</Texts>
                                                     <Data>Data:100</Data>
                                                     <Content>Content:No</Content>
                                                     <Roaming>Roaming:Y + 2000</Roaming>
                                                     <Monthly>Monthly:398</Monthly>
                                                     <Upfront>Upfront:0</Upfront>
                                                 </Row>
                                                 <Row>
                                                     <Minutes>Minutes:99</Minutes>
                                                     <Texts>Texts:92569</Texts>
                                                     <Data>Data:10</Data>
                                                     <Content>Content:No</Content>
                                                     <Roaming>Roaming:Y + 2000</Roaming>
                                                     <Monthly>Monthly:38</Monthly>
                                                     <Upfront>Upfront:0</Upfront>
                                                 </Row>
                                             </SubCategory>
                                         </Tariff>
                                     </Contract>
                                 </Device>
                             </Category>
                         </DPS>

希望它能激發一些想法。 再次,對VB感到抱歉。 我確實嘗試過將其轉換。

暫無
暫無

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

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