Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何基于IndexOf设置MemoryStream位置,以分割XML文档序列?_C#_Xml_Streamreader_Memorystream - Fatal编程技术网

C# 如何基于IndexOf设置MemoryStream位置,以分割XML文档序列?

C# 如何基于IndexOf设置MemoryStream位置,以分割XML文档序列?,c#,xml,streamreader,memorystream,C#,Xml,Streamreader,Memorystream,我有一个伪XML文件,其中包含5个小XML,如下所示: 我试图实现的是使用MemoryStream和以下代码分别为这些XML创建一个新文件: int flag = 0; byte[] arr = Encoding.ASCII.GetBytes(File.ReadAllText(@"C:\\Users\\Aleksa\\Desktop\\testTxt.xml")); for (int i = 0; i <= 5; i++) { MemoryStream mem = new M

我有一个伪XML文件,其中包含5个小XML,如下所示:

我试图实现的是使用
MemoryStream
和以下代码分别为这些XML创建一个新文件:

int flag = 0;

byte[] arr = Encoding.ASCII.GetBytes(File.ReadAllText(@"C:\\Users\\Aleksa\\Desktop\\testTxt.xml"));

for (int i = 0; i <= 5; i++)
{
    MemoryStream mem = new MemoryStream(arr);
    mem.Position = flag;
    StreamReader rdr = new StreamReader(mem);

    string st = rdr.ReadToEnd();

    if (st.IndexOf("<TestNode") != -1 && (st.IndexOf("</TestNode>") != -1 || st.IndexOf("/>") != -1))
    {
        int curr = st.IndexOf("<TestNode");
        int end = st.IndexOf("\r");
        string toWrite = st.Substring(st.IndexOf("<TestNode"), end);
        File.WriteAllText(@"C:\\Users\\Aleksa\\Desktop\\" + i.ToString() + ".xml", toWrite);
        flag += end;
    }
    Console.WriteLine(st);
}
int标志=0;
byte[]arr=Encoding.ASCII.GetBytes(File.ReadAllText(@“C:\\Users\\Aleksa\\Desktop\\testTxt.xml”);

对于(inti=0;i而言,您的输入流由——即一系列连接在一起的XML组成

您可以通过使用创建的
XmlReader
读取此类流。从:

片段

确保XML数据符合格式良好的XML 1.0文档片段的规则

此设置接受具有多个根元素或顶层文本节点的XML数据

以下扩展方法可用于此任务:

public static class XmlReaderExtensions
{
    public static IEnumerable<XmlReader> ReadRoots(this XmlReader reader)
    {
        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element)
            {
                using (var subReader = reader.ReadSubtree())
                    yield return subReader;
            }
        }
    }

    public static void SplitDocumentFragments(Stream stream, Func<int, string> makeFileName, Action<string, IXmlLineInfo> onFileWriting, Action<string, IXmlLineInfo> onFileWritten)
    {
        using (var textReader = new StreamReader(stream, Encoding.UTF8, true, 4096, true))
        {
            SplitDocumentFragments(textReader, makeFileName, onFileWriting, onFileWritten);
        }
    }

    public static void SplitDocumentFragments(TextReader textReader, Func<int, string> makeFileName, Action<string, IXmlLineInfo> onFileWriting, Action<string, IXmlLineInfo> onFileWritten)
    {
        if (textReader == null || makeFileName == null)
            throw new ArgumentNullException();
        var settings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment, CloseInput = false };
        using (var xmlReader = XmlReader.Create(textReader, settings))
        {
            var lineInfo = xmlReader as IXmlLineInfo;
            var index = 0;

            foreach (var reader in xmlReader.ReadRoots())
            {
                var outputName = makeFileName(index);
                reader.MoveToContent();
                if (onFileWriting != null)
                    onFileWriting(outputName, lineInfo);
                using(var writer = XmlWriter.Create(outputName))
                {
                    writer.WriteNode(reader, true);
                }
                index++;
                if (onFileWritten != null)
                    onFileWritten(outputName, lineInfo);
            }
        }
    }
}
输出将类似于:

  • 不要使用
    Encoding.ASCII
    读取XML流,这将从文件中删除所有非英语字符。相反,请使用
    Encoding.UTF8
    和/或从或XML声明中检测编码


  • 演示小提琴。

    为什么不把你读过的字符串放在
    元素中,这样你就可以把它读成XML,然后用XML工具把它拆开?因为这是一种实践,我必须遵循文档规范-我从远程服务器得到无限的流字符串放在文件中,然后使用MemoryStream我必须把它拆开像这样从文件中提取字符串,并为每个字符串创建一个单独的xml文件,我不知道在这种情况下将字符串封装在dummynode中是否合适,但如果给它一个机会,我如何将其封装在dummynode中?请记住,文件一直都有新字符串,然后创建单独的小xml?@Dami另外,这里只有5个迷你xml,因为实际上我没有远程服务器向我发送字符串,但我必须编写逻辑,就像它发送字符串一样。最后一个迷你xml字符串没有结束标记,但由于文档的缘故,它被封装在自己的内部,一些字符串被“发送”像这样…我知道很奇怪,但这是我的家庭作业ZZZY你可以通过设置
    XmlReaderSettings{ConformanceLevel=ConformanceLevel.Fragment}来读取这样的XML片段流
    事先。无需任何手册。请参阅或。此处演示如何使用
    ConformanceLevel=ConformanceLevel.Fragment
    。这是否满足您的需要?由于您提到“家庭作业”,您可能有一些额外的限制,不允许使用此解决方案。非常感谢您的帮助和耐心,我非常感谢!)
    var fileName = @"C:\\Users\\Aleksa\\Desktop\\testTxt.xml";
    var outputPath = ""; // The directory in which to create your XML files.
    using (var stream = File.OpenRead(fileName))
    {
        XmlReaderExtensions.SplitDocumentFragments(stream,
                                                   index => Path.Combine(outputPath, index.ToString() + ".xml"),
                                                   (name, lineInfo) => 
                                                   {
                                                       Console.WriteLine("Writing {0}, starting line info: LineNumber = {1}, LinePosition = {2}...", 
                                                                         name, lineInfo?.LineNumber, lineInfo?.LinePosition);
                                                   },
                                                   (name, lineInfo) => 
                                                   {
                                                       Console.WriteLine("   Done.  Result: ");
                                                       Console.Write("   ");
                                                       Console.WriteLine(File.ReadAllText(name));
                                                   });
    }
    
    Writing 0.xml, starting line info: LineNumber = 1, LinePosition = 2...
       Done.  Result: 
       <?xml version="1.0" encoding="utf-8"?><TestNode active="1" lastName="l"><Foo /> </TestNode>
    Writing 1.xml, starting line info: LineNumber = 2, LinePosition = 2...
       Done.  Result: 
       <?xml version="1.0" encoding="utf-8"?><TestNode active="2" lastName="l" />
    Writing 2.xml, starting line info: LineNumber = 3, LinePosition = 2...
       Done.  Result: 
       <?xml version="1.0" encoding="utf-8"?><TestNode active="3" lastName="l"><Foo />  </TestNode>
    
    ... (others omitted).
    
    using (var textReader = new StringReader(st))
    {
            XmlReaderExtensions.SplitDocumentFragments(textReader, 
    // Remainder as before