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



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

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

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 作为字符串。

编辑:为了澄清,每个XML只有一个"根"节点,标题我在那里,它可能不在那里。 所以有些情况。

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

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

所有 xml 字符串都以一种方式相似,它们都以</root>标记结尾,因此您可能只想在遇到</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>

听起来您在根级别有多个节点,这被称为"格式不正确"。 因此,您必须使用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:temptest.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);
}
}
}
}
}

最新更新