[英]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文檔,它將為您創建DataTable
, DataColumn
和DataRow
對象。 如果要隨后將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.