Java 从输入流中连续读取XML作为字符串
我试图从一个连续的流中读取XML数据,我需要将每个XML存储在一个字符串列表中。我只需要原始XML数据作为字符串数据,而不是DOM或SAX或任何类型的序列化。 我目前正在将输入流读取到扫描仪中,并使用delimeter,但我需要说明一个不存在XML头的场景Java 从输入流中连续读取XML作为字符串,java,xml,Java,Xml,我试图从一个连续的流中读取XML数据,我需要将每个XML存储在一个字符串列表中。我只需要原始XML数据作为字符串数据,而不是DOM或SAX或任何类型的序列化。 我目前正在将输入流读取到扫描仪中,并使用delimeter,但我需要说明一个不存在XML头的场景 String xml = "<?xml version=\"1.0\" standalone=\"yes\"?><root></root>" String xml=“” 或 stringxml=” 我
String xml = "<?xml version=\"1.0\" standalone=\"yes\"?><root></root>"
String xml=“”
或
stringxml=”
我当前的实现是
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
}
}
try(Socket=server.accept()){
try(InputStream in=socket.getInputStream()){
最终扫描仪=新扫描仪(新InputStreamReader(在“UTF-8”中);
scanner.useDelimiter(“”;//找到XMl标记时停止流读取
}
}
可以为xml头或第一个节点编写正则表达式吗?(第一个节点始终相同)
我曾尝试使用XMLStreamReader,但据我所知,它只能通过遍历来解析数据。这很好,但我最终每次都需要将整个XML作为字符串
编辑:为了澄清这一点,每个XML只有一个“根”节点,我的头可能在那里,但它可能不在。因此,在某些情况下
<?xml version=\"1.0\" standalone=\"yes\"?>
<root>
</root>
<?xml version=\"1.0\" standalone=\"yes\"?>
<root>
</root>
<root>
</root>
我想将这三个xml都作为字符串处理,因为所有xml字符串在一个方面都是相似的,它们都以一个
标记结尾,所以您可能只需要逐个字符读取,并在遇到
标记时剪切
下面是一个使用示例字符串的示例
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);
String s=“”+
"" +
"" +
"" +
"" +
"" +
"" +
"";
InputStream in=newbytearrayinputstream(s.getBytes());
INTC;
StringBuilder xmlString=新的StringBuilder();
列表=新的ArrayList();
而((c=in.read())!=-1){
append((char)c);
//当你得到一个结束标记时,检查它是否正确
if((char)c=='>'&&xmlString.toString().endsWith((“”)){
add(xmlString.toString());
xmlString=新的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>
听起来您在根级别有多个节点,称为“格式不正确”。因此您必须使用设置为“碎片”的XmlReader。请参阅下面的代码:
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);
}
}
}
}
}
当你说第一个节点总是相同的时候,你指的是
标记?因此“poppap”
应该给你一个包含两个字符串的列表,对吗?是的,根级别的节点总是相同的。而且只有一个,所以它更像poppap”和标记?溪流中会有几个吗?您能给出一个流的完整示例和所需的字符串列表吗?可以,但有些xml可能有,有些可能没有。我在处理一个可以捕获任何一种场景的正则表达式时遇到了麻烦。你永远不应该在xml上使用正则表达式。总有更好的办法。如果您需要删除标识行,您可以使用streamreader读取文件并在使用xmlreader解析之前过滤这些行。有很多人不喜欢片段化xml,但它们有非常有用的用途。您可以在日志文件中使用它们,在日志文件中,您需要将数据附加到文件的末尾,并且以后可以轻松地解析日志文件。您不应该让xml标识行出现多次,这会显示本例中可能发生的情况。
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);
}
}
}
}
}