繁体   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