[英]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.