【问题标题】:XmlWriter -write from reader (xml fragment)XmlWriter - 从阅读器写入(xml 片段)
【发布时间】:2016-03-11 07:27:55
【问题描述】:

是否可以将所有内容(xml 片段)从一个流(使用 xmlReader)复制到第二个流(xmlWriter)。

我有一些返回 xml 片段的程序。

<item></item>
<item></item>
<item></item>
<item></item>
<item></item>

using (XmlWriter writer = XmlWriter.Create(stream, _settings))
{
    writer.WriteStartElement(typeName);
    writer.WriteAttributeString("RowVersion", rowVersion);
    for (int i = 1; i <= packagesCount; i++)
    {
         cmd.Parameters["@packageNumber"].Value = i;
         using (var r = cmd.ExecuteXmlReader())
         {
              //need copy all fragment from reader
         }
                    writer.WriteEndElement();

                }
    }

有类似 writer.WriteNode(reader,true) 的方法,但是使用它我需要迭代所有元素。当我在一个片段中有 10000 个元素时,它无效。我只需要复制所有内容。此外,这个片段可能非常大,这就是为什么我更喜欢使用流,而不是将其保存在字符串中

【问题讨论】:

  • 你试过 XDocument 类吗? msdn.microsoft.com/en-us/library/…
  • 当然我可以使用 XDocument - XDocument.Load(XmlReader) 和 XDocument.WriteTo(XmlWriter) 执行此操作,但使用此方法我需要将所有片段保存在 XDocment 实例中。

标签: c# xml stored-procedures xmlreader xmlwriter


【解决方案1】:

一个旧帖子,但对某人可能有用。

我必须处理相当大 (>50MB) 的 XML 文件。我需要从中提取一个片段并分别处理这些片段。所以我这样做了:

  class Program
  {

    static void processXML(string xml)
    {

      SqlServerTypes.Utilities.LoadNativeAssemblies(AppDomain.CurrentDomain.BaseDirectory);

      XmlReader reader = XmlReader.Create(xml);

      XmlWriterSettings settings = new XmlWriterSettings
      {
        ConformanceLevel = ConformanceLevel.Auto
      };
      var output_file = "output.xml";

      if (File.Exists(output_file))
      {
        File.Delete(output_file);
      }

      XmlWriter writer = XmlWriter.Create("output.xml", settings);
      try
      {

        Console.WriteLine("Processing: " + xml);
        Console.WriteLine("Outputting to: " + Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "output.xml"));
        //extract all namespaces used in document
        XPathDocument x = new XPathDocument(reader);
        XPathNavigator foo = x.CreateNavigator();
        foo.MoveToFollowing(XPathNodeType.Element);
        IDictionary<string, string> Namespaces = foo.GetNamespacesInScope(XmlNamespaceScope.All);

        reader = XmlReader.Create(xml);
        var elementFullName_ = "";
        var elementName_ = "";
        var elementToFind = "sl:stand";
        var elementsFound = 0;
        var prefix_ = "";
        var text_ = "";
        var whiteSpace_ = "";
        while (reader.Read())
        {
          switch (reader.NodeType)
          {
            case XmlNodeType.Element:
              elementFullName_ = reader.Name;
              if (elementFullName_ == elementToFind)
              {
                //avoid processing the file if XmlWriter just started
                if (writer.WriteState != WriteState.Start)
                {
                  writer.Flush();
                  writer.Close();
                  //here process the file for whatever you want
                  if (File.Exists(output_file))
                  {
                    File.Delete(output_file);
                  }
                  writer = XmlWriter.Create("output.xml", settings);
                }
                elementsFound = 1;
              }
              else if(elementsFound > 0)
              {
                elementsFound++;
              }
              var arr = reader.Name.Split(':');
              if (arr.Length == 2)
              {
                prefix_ = arr[0];
                elementName_ = arr[1];
                if (elementsFound > 0)
                  writer.WriteStartElement(arr[0], arr[1], Namespaces[arr[0]]);
              }
              else
              {
                prefix_ = "";
                elementName_ = reader.Name;
                if (elementsFound > 0)
                  writer.WriteStartElement(reader.Name);
              }

              if (elementsFound > 0 && reader.HasAttributes)
                writer.WriteAttributes(reader, true);

              if (elementsFound > 0 && reader.IsEmptyElement)
                writer.WriteEndElement();

              break;
            case XmlNodeType.EndElement:

              if (elementsFound > 0)
              {
                writer.WriteEndElement();
              }

              if (elementsFound > 0)
              {
                elementsFound--;
              }

              if (elementsFound == 0)
              {
              }

              break;
            case XmlNodeType.Text:
              if (elementFullName_ == "gml:posList")
              {
                text_ = reader.Value;
              }
              if (elementsFound > 0)
                writer.WriteString(reader.Value);
              break;
            case XmlNodeType.Whitespace:
              if (elementFullName_ == "gml:posList")
              {
                whiteSpace_ = reader.Value;
              }
              if (elementsFound > 0)
                writer.WriteWhitespace(reader.Value);
              break;
          }
        }

      }
      finally
      {
        reader.Close();
        writer.Close();
      }
    }
    static void Main(string[] args)
    {

      var xml = "";


      if (args.Length == 0 || !File.Exists(args[0]))
      {
        Console.WriteLine("Please, provide a valid XML file as a commandline parameter");
        return;
      }

      xml = args[0];

      processXML(xml);

      Console.WriteLine("Done!");
    }
  }

注意:有些条件对您来说并不重要,因此您可以删除它们。

【讨论】:

    猜你喜欢
    • 2015-09-09
    • 1970-01-01
    • 2010-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-15
    • 1970-01-01
    相关资源
    最近更新 更多