[英]most efficient way in c# to parse a large Xml string (to expand DTD references, add new lines etc)
我有一个提供大Xml字符串的接口,该字符串是有效XML,但可能不是标准格式(例如,缺少指定默认名称空间的前缀),或者没有任何行尾,或者需要扩展内联DTD中的实体。 基本上,我需要使用可以处理内联DTD定义的标准Xml解析器来解析这些字符串。 此字符串数据的范围从几个字符到千兆字节。
目前,我正在使用以下代码(这种简单的解析似乎能够解决我上面提到的问题):
XDocument doc = XDocument.Parse(LargeXmlString);
var settings = new XmlWriterSettings();
settings.Indent = true;
settings.Encoding = Encoding.Unicode;
//more settings
StringBuilder parsedOutput = new StringBuilder();
using (XmlWriter xmlWriter =
XmlWriter.Create(parsedOutput, settings))
{
doc.WriteTo(xmlWriter);
}
尽管这很容易使用,但我不确定与使用其他一些.net xml解析类(例如XmlReader / XmlTextReader或XmlDocument等)相比有多好/不好?
使用.net / c#支持的类执行此操作的最佳/最有效方法是什么(可能无需编写大量新代码)?
谢谢你的帮助
`<?xml version="1.0" encoding="UTF-8"?><Catalogue xmlns="http://www.somewhere.org/BookCatalogue" xmlns:cat="http://www.somewhere.org/BookCatalogue" xmlns:html="http://www.somewhere.org/HTMLCatalogue" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.somewhere.org/BookCatalogue txjsgen14.txt"><cat:Magazine><Title>Natural Health</Title><Author>October</Author><Date>December, 1999</Date><Volume>12</Volume>.....`
转换为
`<?xml version="1.0" encoding="utf-8"?>
<cat:Catalogue xmlns="http://www.somewhere.org/BookCatalogue" xmlns:cat="http://www.somewhere.org/BookCatalogue" xmlns:html="http://www.somewhere.org/HTMLCatalogue" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.somewhere.org/BookCatalogue txjsgen14.txt">
<cat:Magazine>
<cat:Title>Natural Health</cat:Title>
<cat:Author>October</cat:Author>
<cat:Date>December, 1999</cat:Date>
<cat:Volume>12</cat:Volume>
<cat:htmlTable>.....`
请注意,基于名称空间声明,在Title和其他元素上添加了cat前缀
谢谢大家的答复。
@困惑对不起,我在混乱中造成的混乱。 实际上,我只需要一个字符串到字符串的转换,其中第一个字符串的格式不正确,XML格式不正确,不扩展DTD实体,没有行距,并且可能缺少前缀等。而第二个字符串应固定所有这些东西。
现在,如果某个组件(例如XmlReader)可以将第一个字符串作为参数,并使其成为规范/正确格式化/扩展的XML,然后以字符串形式返回,那么我只需要一个组件。 在上面的示例中,解析由XDocument完成,格式由XmlWriter完成。 而且我什至不确定谁来扩展实体,解析器或XmlWriter。 可能是作家。
目前,我将尝试使用XmReader和XmlWriter的组合,其中XmlReader读取第一个字符串,而XmlWriter写入格式化的字符串(由XmlWriter所使用的XmlWriterSettings指定)。 让我知道是否有更好的方法。
对于大型xml,请始终使用XmlReader来防止出现内存不足错误。 下面的代码使用xml linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string xml =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<cat:Catalogue xmlns=\"http://www.somewhere.org/BookCatalogue\" xmlns:cat=\"http://www.somewhere.org/BookCatalogue\" xmlns:html=\"http://www.somewhere.org/HTMLCatalogue\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.somewhere.org/BookCatalogue txjsgen14.txt\">" +
"<cat:Magazine>" +
"<cat:Title>Natural Health</cat:Title>" +
"<cat:Author>October</cat:Author>" +
"<cat:Date>December, 1999</cat:Date>" +
"<cat:Volume>12</cat:Volume>" +
"<cat:htmlTable>" +
"</cat:htmlTable>" +
"</cat:Magazine>" +
"<cat:Magazine>" +
"<cat:Title>Natural Health</cat:Title>" +
"<cat:Author>October</cat:Author>" +
"<cat:Date>December, 1999</cat:Date>" +
"<cat:Volume>12</cat:Volume>" +
"<cat:htmlTable>" +
"</cat:htmlTable>" +
"</cat:Magazine>" +
"</cat:Catalogue>";
StringReader sReader = new StringReader(xml);
XmlReader xReader = XmlReader.Create(sReader);
xReader.MoveToContent();
XNamespace ns = xReader.LookupNamespace(xReader.Prefix);
while (!xReader.EOF)
{
if (xReader.LocalName != "Magazine")
{
xReader.ReadToFollowing("Magazine", ns.NamespaceName);
}
if(!xReader.EOF)
{
XElement magazine = (XElement)XElement.ReadFrom(xReader);
string title = (string)magazine.Element(ns + "Title");
}
}
}
}
}
您基本上可以执行示例中的操作,但是可以使用XmlReader
:
XmlReader xmlReader = ...;
using (XmlWriter xmlWriter = ...)
{
xmlWriter.WriteNode(reader, true);
}
这将是最有效的方法-逐节点流式传输文档,而不是在写入之前将整个内容读取到内存中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.