[英]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.