簡體   English   中英

如何在.NET中解析字符串中的XML?

[英]How to parse XML in a string in .NET?

大家好,StackOverflowers,

我在.NET函數之一中收到一個字符串。 從XML Visualizer查看時,該字符串如下所示:

- <root>
- <Table>
  <ID>ABC-123</ID>
  <CAT>Housekeeping</CAT>
  <DATE>21-JUN-2009</DATE>
  <REP_BY>John</REP_BY>
  <LOCATION>Head Office</LOCATION>
</Table>
- <Table>
  <ID>ABC-124</ID>
  <CAT>Environment</CAT>
  <DATE>23-JUN-2009</DATE>
  <REP_BY>Michelle</REP_BY>
  <LOCATION>Block C</LOCATION>
</Table>
- <Table>
  <ID>ABC-125</ID>
  <CAT>Staging</CAT>
  <DATE>21-JUN-2009</DATE>
  <REP_BY>George</REP_BY>
  <LOCATION>Head Office</LOCATION>
</Table>  
- <Table>
  <ID>ABC-123</ID>
  <CAT>Housekeeping</CAT>
  <DATE>21-JUN-2009</DATE>
  <REP_BY>John</REP_BY>
  <LOCATION space="preserve" xmlns="http://www.w3.org/XML/1998/namespace" /> 
</Table>  
</root>  

我需要解析此字符串,以便可以將數據寫入一個數據表,該數據表的列是每個數據的xml標記。

在上面的文本中,我將有一個數據表,該表有5列,分別是ID,CAT,DATE,REP_BY和LOCATION,它們將包含4行數據。

在第四個標記中,請注意,該標記沒有任何數據,而是標記為space =“ preserve”。 這意味着我要放置在數據表中的數據對於第四行的LOCATION列將為空白。

我該如何實現? 樣本代碼將不勝感激。 謝謝。

使用XmlReader類。 此類很快速,並且不占用大量內存,但是讀取xml可能很困難。

using (StringReader strReader = new StringReader(yourXMLString))
{
    using (XmlReader reader = XmlReader.Create(strReader))
    {
        while (reader.Read())
        {
            if(reader.Name == "Table" && reader.NodeType == reader.NodeType == XmlNodeType.Element)
            {
                using(XmlReader tableReader = reader.ReadSubtree())
                {
                    ReadTableNode(tableReader);
                }
            }
        }
    }
}

private void ReadTableNode(XmlReader reader)
{
    while (reader.Read())
    {
        if(reader.Name == "ID" && reader.NodeType == reader.NodeType == XmlNodeType.Element)
            //do something
        else if(reader.Name == "CAT" && reader.NodeType == reader.NodeType == XmlNodeType.Element)
            //do something

       //and continue....
    }
}

要獲取當前節點的屬性,請使用:

string value = reader.GetAttribute(name_of_attribute);

要獲取元素的內部文本:

string innerText =  reader.ReadString();

使用XmlDocument類。 此類很慢,但是由於加載了整個xml,因此操作和讀取xml非常容易。

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(yourXMLString);
//do something

使用XDocument類。 使用XDocument的優點是可以直接並同時訪問元素。 該類還使用LINQ的功能來查詢xml文檔。

using(StringReader tr = new StringReader(yourXMLString))
{
    XDocument doc = XDocument.Load(tr);
    //do something
}

這可能是將XML轉換為表格形式的最簡單解決方案。 使用正則表達式扔掉屬性並不是那么聰明(而且安全),但是我不喜歡System.Xml API和.NET 2.0中的LINQ to XML在這方面是不可行的。

using System;
using System.Data;
using System.IO;
using System.Text.RegularExpressions;

namespace GeneralTestApplication
{
    class Program
    {
        private static void Main()
        {
            String input = @"<root><Table> [...] </root>";

            input = Regex.Replace(input, @" [a-zA-Z]+=""[^""]*""", String.Empty);

            DataSet dataSet = new DataSet();

            dataSet.ReadXml(new StringReader(input));

            foreach (DataRow row in dataSet.Tables[0].Rows)
            {
                foreach (DataColumn column in dataSet.Tables[0].Columns)
                {
                    Console.Write(row[column] + " | ");
                }
                Console.WriteLine();
            }

            Console.ReadLine();
        }
    }
}

更新

或者使用System.Xml擺脫該屬性。

XmlDocument doc = new XmlDocument();

doc.Load(new StringReader(input));

foreach (XmlNode node in doc.SelectNodes("descendant-or-self::*"))
{
    node.Attributes.RemoveAll();
}

input = doc.OuterXml;

但這是行不通的,因為最后一個LOCATION元素上的XML名稱空間仍然保留,並且DataSet.LoadXml()抱怨說沒有兩列名為LOCATION列。

不要使用字符串解析。 嘗試使用一些xml庫( Linq有一些對象可能會幫助您)。 您可能會輕松得多。

我相信您可以簡單地使用ADO.NET DataSet類的ReadXml方法來讀取該格式的XML文檔,它將為您創建DataTableDataColumnDataRow對象。 如果要隨后將DATE列的數據類型轉換為DateTime則需要編寫一些轉換方法。 但是除此之外,您根本不必使用XML。

編輯

我從Daniel Bruckner的帖子中看到,奇數名稱空間中的LOCATION元素帶來了問題。 好了,很容易解決:

    XmlDocument d = new XmlDocument();
    d.LoadXml(xml);

    XmlNamespaceManager ns = new XmlNamespaceManager(d.NameTable);
    ns.AddNamespace("n", "http://www.w3.org/XML/1998/namespace");
    foreach (XmlNode n in d.SelectNodes("/root/Table/n:LOCATION", ns))
    {
        XmlElement loc = d.CreateElement("LOCATION");
        n.ParentNode.AppendChild(loc);
        n.ParentNode.RemoveChild(n);
    }

    DataSet ds = new DataSet();
    using (StringReader sr = new StringReader(d.OuterXml))
    {
        ds.ReadXml(sr);
    }

我自己不是xml的忠實擁護者,我需要將其用作網格的數據源以使其可視化。 我從FileNet映像服務器獲得了xml格式的一些輸出,並且需要將其中的一部分取出來填充數據庫。 我正在做的是HTH:

  Dim dsXML As DataSet
  Dim drXML As DataRow
  Dim rdr As System.IO.StringReader
  Dim docs() As String
  Dim SQL As String
  Dim xml As String
  Dim fnID As String

docs = _fnP8Dev.getDocumentsXML(_credToken, _docObjectStoreName, _docClass, "ReferenceNumber=" & fnID, "")
xml = docs(0)
If (InStr(xml, "<z:row") > 0) Then
 RaiseEvent msg("Inserting images for reference number " & fnID)
 rdr = New System.IO.StringReader(xml)
 dsXML = New DataSet
 dsXML.ReadXml(rdr)

 For Each drXML In dsXML.Tables(dsXML.Tables.Count - 1).Rows
   SQL = "Insert into fnImageP8 values ("
   SQL = SQL & "'" & drXML("Id") & "', "
   Try
    SQL = SQL & "'" & drXML("DocumentTitle") & "', "
   Catch ex As Exception
    SQL = SQL & "null, "
   End Try

暫無
暫無

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

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