【问题标题】:Reading XML string in .Net在 .Net 中读取 XML 字符串
【发布时间】:2013-11-18 12:12:29
【问题描述】:

有一个 sp 返回超过 300 行,其中一列具有 FOR XML PATH 格式的值。其他列有正常值。

<row>
  <DocType>1</DocType>
  <GeneralName>CV</GeneralName>
  <StartDate>1900-12-31</StartDate>
  <EndDate>1900-12-31</EndDate>
  <CertNo></CertNo>
</row>

如何读取 .Net 中以下元素的值并将它们分配给变量或对象。

<DocType>
<GeneralName>
<StartDate>
<EndDate>
<CertNo>

添加

我试过下面的代码,看起来还可以。

         Dim doc As New XmlDocument()
    doc.LoadXml(xmlString)
    Dim DocType As XmlNode = doc.SelectSingleNode("/row/DocType")
    If Not (DocType Is Nothing) Then
        Dim nr As New XmlNodeReader(DocType)
        While nr.Read()
            MsgBox(nr.ReadInnerXml)
        End While
    End If

有没有其他有效的方法?

【问题讨论】:

  • 有效地定义:这是不是运行得不够快?您发现并评估了哪些其他在 .NET 中读取 XML 的方法?
  • 主要关注的是我必须循环遍历并创建一个新的 XMLDocument 对象的行数。不会超过 600 行。我也遇到过 LINQ to XML。

标签: .net xml vb.net


【解决方案1】:

更新 - 我刚刚意识到标签已更改为 vb.net 但框架类是相同的,所以我希望它仍然有用。

你可以使用XDocument

//assuming that xml contains the string result XML:
    void Main()
    {
        var xml = GoGetSomeXML();//your sp call here, etc.
        var xd = XDocument.Parse(xml);
        foreach (var row in xd.Descendants().Where(x=>x.Name.LocalName=="row"))
        {
           var DocType = GetSubElementValue(row,"DocType");
           var GeneralName = GetSubElementValue(row,"GeneralName");
           var StartDate = GetSubElementValue(row,"StartDate");
           var EndDate = GetSubElementValue(row,"EndDate");
           var CertNo = GetSubElementValue(row,"CertNo");
           Console.WriteLine("{0} {1} {2} {3} {4}",DocType,GeneralName,StartDate,EndDate,CertNo);
        }
    }

    object GetSubElementValue(XElement container, string subElementName)
    {
       var subElement = container.Descendants().FirstOrDefault(d=>d.Name.LocalName==subElementName);
      if (subElement==null) return null;
      return subElement.Value;
    }

生产

1 CV 1900-12-31 1900-12-31 

此外,如果您的结果集可能不会改变并且您可以完全控制数据类型等,您还可以考虑使用XmlSerializer 并定义一个代表结果集中各种元素的类:

void Main()
{
    var xd = XDocument.Parse(xml);
    var ser =new XmlSerializer(typeof(row));    
    foreach (var rowElement in xd.Descendants().Where(x=>x.Name.LocalName=="row"))
    {
     using (var reader = rowElement.CreateReader())
     {
       var row1 = ser.Deserialize(reader) as row;
       Console.WriteLine(row1);
      }
    }
}


public class row
{
  public int DocType {get;set;}
  public string GeneralName{get;set;}
  public DateTime StartDate{get;set;}
  public DateTime EndDate{get;set;}
  public string CertNo{get;set;}
}

请注意,您可以使用各种attributes 来控制 XML 如何映射到 ClassName 和 Properties,所以这是一个非常非常基本的示例 - 当您使用 @987654330 时,类名不必是“row” @class 等等……

序列化器路由对于大量数据可能是最有效的,尽管对于 300 行我不确定您会看到多大差异。

【讨论】:

  • 谢谢,尝试了第一个示例,效果很好。你认为这种方法比 XML Parse (XMLReader) msdn.microsoft.com/en-us/library/cc189056%28v=vs.95%29.aspx
  • 看到了这个链接; stackoverflow.com/questions/1505075/…
  • 个人,我这样做是因为我发现 Linq-To-XML 语法更“自然”并且更容易学习 - 如果您是 XML Parsing 的新手,那么您可以恕我直言,不会出错。你有一个很好的链接。虽然序列化方法将是最快的,但在您的情况下,这实际上取决于您必须处理多少数据以及不同 API 对您的舒适程度!
【解决方案2】:

您或许可以快速将 XML 数据转换为数据集:

Imports System.Xml
...
Public Function GetXMLDataset(XMLText As String) As DataSet
    Try
        Dim ds As New DataSet
        Dim xd As New XmlDocument
        xd.LoadXml(XMLText)
        ds.ReadXml(New XmlNodeReader(xd), XmlReadMode.InferSchema)
        Return ds
    Catch ex As Exception
        MsgBox(ex.Message)
        Return Nothing
    End Try
End Function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-19
    • 2021-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-08
    • 2011-04-24
    • 1970-01-01
    相关资源
    最近更新 更多