从输入流中连续读取XML作为字符串

时间:2018-05-17 16:52:25

标签: java xml

我试图从连续流中读取XML数据,我需要将每个XML存储在字符串列表中。我只需将原始XML数据作为字符串数据而不是DOM或SAX或任何类型的序列化。 我目前正在从InputStream读取扫描仪并使用分隔符,但我需要考虑不存在XML标头的情况。

String xml = "<?xml version=\"1.0\" standalone=\"yes\"?><root></root>"

OR

String xml = "<root></root>

我目前的实施是

try (Socket socket = server.accept()) {
    try (InputStream in = socket.getInputStream()) {
        final Scanner scanner = new Scanner(new InputStreamReader(in, "UTF-8"));
        scanner.useDelimiter("<\\?xml.*?\\?>");  //Stop stream read when XMl tag is found
    }
}

是否可以编写一个占xml头或第一个节点的正则表达式? (第一个节点始终相同)

我试图使用XMLStreamReader,但据我所知,只有通过遍历来解析数据。没关系,但我最终每次都需要整个XML作为String。

编辑:为了澄清,只有一个&#34; root&#34;每个XML的节点,标题我在那里,它可能不会。所以有些情况。

<?xml version=\"1.0\" standalone=\"yes\"?>
<root>
</root>
<?xml version=\"1.0\" standalone=\"yes\"?>
<root>
</root>
<root>
</root>

我想将所有这三个xml作为字符串处理

2 个答案:

答案 0 :(得分:0)

所有xml字符串在某种程度上都是相似的,它们都以</root>标记结尾,因此您可能只想通过char读取char并在遇到</root>标记时剪切。

以下是使用示例字符串的示例。

String s = "<?xml version=\"1.0\" standalone=\"yes\"?>" +
        "<root>" +
        "</root>" +
        "<?xml version=\"1.0\" standalone=\"yes\"?>" +
        "<root>" +
        "</root>" +
        "<root>" +
        "</root>";

InputStream in = new ByteArrayInputStream(s.getBytes());

int c;
StringBuilder xmlString = new StringBuilder();
List<String> list = new ArrayList<>();
while ((c = in.read()) != -1) {
    xmlString.append((char)c);
    // When you get a closing tag, check if it is </root>
    if( (char)c == '>' && xmlString.toString().endsWith(("</root>")) ) {
        list.add(xmlString.toString());
        xmlString = new StringBuilder();
    }
}
in.close();

list.forEach(System.out::println);

这输出3个字符串

<?xml version="1.0" standalone="yes"?><root></root>
<?xml version="1.0" standalone="yes"?><root></root>
<root></root>

答案 1 :(得分:-1)

听起来你在根级别有多个节点,称为“Not Well Formed”。所以你必须使用XmlReader,并将设置设置为“Fragmented”。请参阅以下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication45
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.ConformanceLevel = ConformanceLevel.Fragment;
            XmlReader reader = XmlReader.Create(FILENAME);

            while (!reader.EOF)
            {
                if (reader.Name != "root")
                {
                    reader.ReadToFollowing("root");
                }
                if (!reader.EOF)
                {
                    XElement root = (XElement)XElement.ReadFrom(reader);
                }
            }

        }

    }
}