如何使用XElement解析使用VB.NET读取xml文件?

时间:2016-03-31 12:00:55

标签: xml vb.net linq xelement

我是解析xml的新手。我尝试了为类似问题提供的解决方案,但我的xml以不同的方式格式化。我有一个xml文件,如下所示,来自外部工具。我从这个工具中得到了这个web响应。

<Entities TotalResults="2">
  <Entity Type="release">
    <Fields>
      <Field Name="name">
        <Value>Release1</Value>
      </Field>
      <Field Name="end-date">
        <Value>2015-05-15</Value>
      </Field>
      <Field Name="req-count">
        <Value>29</Value>
      </Field>
      <Field Name="usedPlans">
        <Value>Plan1</Value>
        <Value>Plan2</Value>
      </Field>      
    </Fields>
    <RelatedEntities />
  </Entity>
  <Entity Type="release">
    <Fields>
      <Field Name="name">
        <Value>Release2</Value>
      </Field>
      <Field Name="end-date">
        <Value>2015-05-15</Value>
      </Field>
      <Field Name="req-count">
        <Value>10</Value>
      </Field>
      <Field Name="usedPlans">
        <Value>Plan5</Value>
        <Value>Plan6</Value>
      </Field>      
    </Fields>
    <RelatedEntities />
  </Entity>
</Entities>

我需要获得以下详细信息 发行名称,结束日期,需求计数,UsedPlans等

第一个版本的示例输出将是

Release Name: Release1
End Date: 2015-05-15
Req Count: 29
Used Plans: Plan1, Plan2

VB.NET代码:

Public Function getReleaseInfo(cookie As String, domain As String, project As String) As RestResponse
    Dim resp As New relResponse()

    Try
        Dim relStartDate As String = ConfigurationManager.AppSettings("RelStartDate").Trim()
        Dim url = (Convert.ToString((Convert.ToString((Convert.ToString(RestUrl + "/rest/domains/") & domain) + "/projects/") & project) + "/releases?query={start-date[>='") & relStartDate) + "'] }"
        Dim request As WebRequest = WebRequest.Create(url)
        request.Headers.Set(HttpRequestHeader.Cookie, cookie)
        Dim result As WebResponse = request.GetResponse()

        Dim responseStream = result.GetResponseStream()
        If responseStream IsNot Nothing Then
            Dim reader = New StreamReader(responseStream)
            Dim output As String = reader.ReadToEnd()
            Dim xml = XElement.Parse(output)

            'below part gives me req-count but is there a better way. 
            'If I do as below, I have to do this for all items that I need

            Dim reqCount = From r In releaseXML...<Field> Where r@.FirstAttribute = "req-count" Select counReq = r.Value

            For Each req In reqCount
                Console.WriteLine(req)
            Next


        End If
    Catch ex As Exception
        resp.Good= False
        resp.Error= ex
    End Try

    Return resp
End Function


Dim reqCount = From r In releaseXML...<Field> Where r@.FirstAttribute = "req-count" Select counReq = r.Value

For Each req In reqCount
    Console.WriteLine(req)
Next

将控制权放在控制台中

29
10

有没有更好的方法呢?

我有以下代码使用C#进行linq查询,它运行正常。不幸的是我无法将其转换为vb.net 我尝试了很多转换器,他们没有给我正确的vb.net版本的查询。我不太喜欢linq纠正它。有人可以为我转换代码。

使用C#代码:

string output = reader.ReadToEnd();
var xml = XElement.Parse(output);
var entities = xml.Descendants("Entity");
var releases = (
                from entity in entities
                select entity.Descendants("Field")
                    into fields
                    select fields as IList<XElement> ?? fields.ToList()
                        into xElements
                        let name = xElements.Single(x => x.Attribute("Name").Value == "name").Value
                        let endDate = xElements.Single(x => x.Attribute("Name").Value == "end-date").Value
                        let reqCount = xElements.Single(x => x.Attribute("Name").Value == "req-count").Value                                    
                        let PlansUsed = xElements.Single(x => x.Attribute("Name").Value == "usedPlans").Value                                                                    
                        select new Release { Name = name, EndDate = endDate, ReqCount = reqCount, PlansUsed = usedPlans }).ToList();

编辑:添加了linq查询的工作C#代码。有人可以将其转换为vb.net。注意:在线转换器和其他工具不提供转换后的代码。

2 个答案:

答案 0 :(得分:3)

谢谢大家的帮助。我设法为我的问题找到了解决方案。 这是有效的代码

Public Function getReleaseInfo(cookie As String, domain As String, project As String) As RestResponse
    Dim resp As New relResponse()

    Try
        Dim url = "http://resturl"
        Dim request As WebRequest = WebRequest.Create(url)
        request.Headers.Set(HttpRequestHeader.Cookie, cookie)
        Dim result As WebResponse = request.GetResponse()

        Dim responseStream = result.GetResponseStream()
        If responseStream IsNot Nothing Then
            Dim reader = New StreamReader(responseStream)
            Dim output As String = reader.ReadToEnd()
            Dim xml = XElement.Parse(output)

             Dim releaseInformation = (From e As XElement In xml.Elements
                                          Let relName = e...<Field>.Single(Function(x) x.Attribute("Name").Value = "name").Value
                                          Let relEndDate = e...<Field>.Single(Function(x) x.Attribute("Name").Value = "end-date").Value
                                          Let relReqCount = e...<Field>.Single(Function(x) x.Attribute("Name").Value = "req-count").Value
                                          Let relUsedPlans = e...<Field>.Single(Function(x) x.Attribute("Name").Value = "usedPlans").Elements.ToList
                                          Select New myReleases With {.relName = relName, .relEndDate = relEndDate, .relReqCount = relReqCount, .relUsedPlans = relUsedPlans}).ToList

                resp.Good = True
                resp.result = releaseInformation

        End If
    Catch ex As Exception
        resp.Good= False
        resp.Error= ex
    End Try

    Return resp
End Function

myReleases class

Public Class myReleases
    Public relName As String
    Public relEndDate As Date
    Public relReqCount As Integer
    Public relUsedPlans As List(Of XElement)
    Public ReadOnly Property usedPlans As List(Of String)
        Get
            Dim plans As List(Of String) = (From p In RelUsedPlans Where Trim(p.Value) <> "" Select p.Value).ToList()
            Return plans                
        End Get
    End Property
End Class

Edit: Changed code to return used plans as a list of values

答案 1 :(得分:2)

尝试这样的事情......这段代码从一个文件&#39; xml.xml&#39;中读取你的XML。到一个字符串然后反序列化为一个对象,然后你可以轻松地获得你想要的数据.....

编辑......新代码.......(包括您的ALMReleases类)

Imports System.IO
Imports System.Text
Imports System.Xml
Imports System.Xml.Serialization

Module Module1

    Sub Main()
        Dim deserializedXML As Entities
        Dim xmlString As String = File.ReadAllText("xml.xml")

        Dim bufXML As Byte() = ASCIIEncoding.UTF8.GetBytes(xmlString)
        Dim ms1 As MemoryStream = New MemoryStream(bufXML)

        Dim serializer As XmlSerializer = New XmlSerializer(GetType(Entities))

        Try
            Using reader As XmlReader = New XmlTextReader(ms1)
                deserializedXML = DirectCast(serializer.Deserialize(reader), Entities)

                Dim releaseInformation = (From e In deserializedXML.Entity Select New ALMReleases With {
                                                                         .relName = e.Fields.Field(0).Value.FirstOrDefault,
                                                                         .relEndDate = e.Fields.Field(1).Value.FirstOrDefault,
                                                                         .relReqCount = e.Fields.Field(2).Value.FirstOrDefault,
                                                                         .relUsedPlans = e.Fields.Field(3).Value.ToList
                                                                         }).ToList
                Dim i = 0
            End Using
        Catch ex As Exception

        End Try
        Console.ReadKey()

    End Sub

End Module

Public Class ALMReleases
    Friend relEndDate As String
    Friend relName As String
    Friend relReqCount As String
    Friend relUsedPlans As List(Of String)
End Class

<XmlRoot(ElementName:="Field")>
Public Class Field
    <XmlElement(ElementName:="Value")>
    Public Property Value() As List(Of String)
        Get
            Return m_Value
        End Get
        Set
            m_Value = Value
        End Set
    End Property
    Private m_Value As List(Of String)
    <XmlAttribute(AttributeName:="Name")>
    Public Property Name() As String
        Get
            Return m_Name
        End Get
        Set
            m_Name = Value
        End Set
    End Property
    Private m_Name As String
End Class

<XmlRoot(ElementName:="Fields")>
Public Class Fields
    <XmlElement(ElementName:="Field")>
    Public Property Field() As List(Of Field)
        Get
            Return m_Field
        End Get
        Set
            m_Field = Value
        End Set
    End Property
    Private m_Field As List(Of Field)
End Class

<XmlRoot(ElementName:="Entity")>
Public Class Entity
    <XmlElement(ElementName:="Fields")>
    Public Property Fields() As Fields
        Get
            Return m_Fields
        End Get
        Set
            m_Fields = Value
        End Set
    End Property
    Private m_Fields As Fields
    <XmlElement(ElementName:="RelatedEntities")>
    Public Property RelatedEntities() As String
        Get
            Return m_RelatedEntities
        End Get
        Set
            m_RelatedEntities = Value
        End Set
    End Property
    Private m_RelatedEntities As String
    <XmlAttribute(AttributeName:="Type")>
    Public Property Type() As String
        Get
            Return m_Type
        End Get
        Set
            m_Type = Value
        End Set
    End Property
    Private m_Type As String
End Class

<XmlRoot(ElementName:="Entities")>
Public Class Entities
    <XmlElement(ElementName:="Entity")>
    Public Property Entity() As List(Of Entity)
        Get
            Return m_Entity
        End Get
        Set
            m_Entity = Value
        End Set
    End Property
    Private m_Entity As List(Of Entity)
    <XmlAttribute(AttributeName:="TotalResults")>
    Public Property TotalResults() As String
        Get
            Return m_TotalResults
        End Get
        Set
            m_TotalResults = Value
        End Set
    End Property
    Private m_TotalResults As String
End Class

使用代码......

  1. 创建一个新的VB.NET控制台应用程序
  2. 将上面的代码复制并粘贴到&#39; Module1&#39;文件(替换自动生成的代码)
  3. 打开文件资源管理器并导航到&#39; \ ... \ bin \ Debug&#39;文件夹(也编译应用程序exe)
  4. 创建一个新文本文件并将其重命名为“xml.xml&#39;
  5. 在记事本中打开xml.xml,粘贴您的XML(与您的问题完全一样)并保存文件
  6. 返回Visual Studio,按F5运行代码.....
  7. 将出现一个控制台窗口,显示您需要的结果

    一旦您使用此代码,您就可以看到它的工作方式和修改方式,以满足您的特定需求......