簡體   English   中英

C#中解析大型Xml字符串的最有效方法(擴展DTD引用,添加新行等)

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

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