[英]How to read multiple tags with same name under child node in a xml file using c#?
For below xml i want to read all row nodes value, as you can see there are multiple row tags under subcategory tag, so for particular subcategory(suppose for SubCategory ID="Standard") i want to fetch all row tags? 对于下面的xml,我想读取所有行节点的值,如您所见,在subcategory标签下有多个行标签,因此对于特定的subcategory(假设SubCategory ID =“ Standard”),我想获取所有行标签? How to do this using c#?
如何使用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>
First, load the XML into an XDocument. 首先,将XML加载到XDocument中。
var xdoc = XDocument.Parse(xml); // Or XDocument.Load(pathToXmlFile), etc....
Then you can query all the SubCategory elements for the one with the ID of "Standard" and lastly ask for all of its child elements, the rows. 然后,您可以在所有SubCategory元素中查询ID为“ Standard”的一个,最后要求其所有子元素(行)。
var rows = xdoc.Descendants("SubCategory")
.Where(sc => sc.Attribute("ID").Value == "Standard")
.Elements();
Edit : To get the actual values from the above XML, this is one way to do it. 编辑 :要从上述XML中获取实际值,这是一种方法。
I made an inline function to get a given element from the row by name and handle stripping out unwanted characters from it. 我做了一个内联函数,以按名称从行中获取给定元素,并处理从中删除不需要的字符。
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
Then, we can use it to get all the expected properties for each row: 然后,我们可以使用它来获取每一行的所有预期属性:
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")
});
For real usage, you'll probably want to make a class with the properties like Minutes, Texts, etc. defined on it if you don't already and then put that class name after the new
keyword where the rows are being selected. 为了实际使用,如果您尚未定义类,则可能要创建一个类,该类具有诸如Minutes,Texts等的属性,然后将该类名放在要选择行的
new
关键字之后。
Edit 2 : With the extra bits of text in each element acknowledged as "typing error", you can skip the inline function altogether and simplify the rowData select to this: 编辑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
});
This VB code could not be converted to C# using the converter I have access to. 无法使用我可以访问的转换器将此VB代码转换为C#。 I knew the XML literal doesn't have a counterpart in C#, but isn't needed for anything but to have some test data.
我知道XML文字在C#中没有对应的文字,但是除了具有一些测试数据外,不需要任何其他内容。
Since the XML seems well structured I created a series of classes that mimics the data. 由于XML看起来结构良好,因此我创建了一系列模拟数据的类。 They are just a starting point because I didn't know the ins and outs of the data.
它们只是一个起点,因为我不知道数据的来龙去脉。
Lets start at the end by looking at each row in Standard. 让我们从查看Standard的每一行开始。 Debugs were added to help visualize.
添加了调试以帮助可视化。
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
Here are the classes. 这是课程。
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
Here is that pesky XML literal that was used to test 这是用来测试的讨厌的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>
Hope it sparks some ideas. 希望它能激发一些想法。 Again, sorry for the VB.
再次,对VB感到抱歉。 I did try to convert it.
我确实尝试过将其转换。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.