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