我正在使用的XML文件未成型,因此无效。它提出了以下问题:
缺少根元素(错误消息:文档末尾的额外内容)
该文件包含多条记录,这是一个包含两条记录的摘录:
<?xml version="1.0" encoding="utf-8"?> <ElementAa xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="some-namespace"> <ElementBa attributeB1="11111" attributeB2="someDate"> <ElementCa attributeC1="someString" attributeC2="someOtherDate"> <ElementDa attributeD1="12345" /> </ElementCa> <ElementEa attributeE1="ABCD" /> </ElementBa> </ElementAa> <?xml version="1.0" encoding="utf-8"?> <ElementAb xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="some-namespace"> <ElementBb attributeB1="22222" attributeB2="AgainDate"> <ElementCb attributeC1="anotherString" attributeC2="yetAnotherDate"> <ElementDb attributeD1="67891" /> </ElementCb> <ElementEb attributeE1="EFGHI" /> </ElementBb> </ElementAb>
为了形成良好和有效,上述文件应该变成这个(如果我错了请纠正我):
<?xml version="1.0" encoding="utf-8"?>
<ElementAa xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="some-namespace">
<ElementBa attributeB1="11111" attributeB2="someDate">
<ElementCa attributeC1="someString" attributeC2="someOtherDate">
<ElementDa attributeD1="12345"/>
</ElementCa>
<ElementEa attributeE1="ABCD"/>
</ElementBa>
<ElementBb attributeB1="22222" attributeB2="AgainDate">
<ElementCb attributeC1="anotherString" attributeC2="yetAnotherDate">
<ElementDb attributeD1="67891"/>
</ElementCb>
<ElementEb attributeE1="EFGHI"/>
</ElementBb>
</ElementAa>
虽然我知道在所有可能的世界中,数据应该是高质量的,不幸的是我将不得不处理一个糟糕的数据集,我正在努力找到一个良好的方法来实现一个良好的形式和有效XML。目前,我编写了2个实用程序方法,删除所有XML声明(使用模式/匹配器进行正则表达式)并注入文件顶部所需的唯一一个,我将要执行类似的操作以删除任何额外的根节点元素并且只保留<ElementAa xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="some-namespace">
我不认为这种方法特别理想,我担心在处理大文件时会出现很大问题,你能帮忙吗?任何建议,建议,潜在的方法将不胜感激!我真的在为所描述的场景寻找一个好的方法。
非常感谢你,
予。
编辑1: 如上所述,XML内容位于.txt文件中,我编写的2个实用程序方法使用公共BufferedReader来读取其内容。我试图在重命名扩展名为.xml的文件之前进行所有“数据清理”(我还有另一个实用程序)并将其提供给JaxB解析器。
编辑2:不幸的是,当我直接从FTP读取文件时,我无法控制XML生成。最好控制多个XML如何连接到我提供摘录的结果中,但这是不可能的。
答案 0 :(得分:1)
基本上,您的任务是为语法编写解析器,该语法与XML的语法有一些相似之处。在为任何语法编写解析器之前,您需要定义该语法是什么:即,指定您的工具将接受哪些输入,可能是根据XML语法的变化。
当然,这将是昂贵的:标准化的目的是降低成本,以便每个人都可以使用相同的语法和相同的解析器,如果人们使用专有的变体,那么生活对每个人来说都会变得更复杂。
到目前为止,您要求我们通过向我们展示一个示例来猜测您的异常XML的语法。好吧,一个例子没有做出规范。更严重的是,为一种未经指定的语言编写解析器,通过不断扩展它来处理越来越多的例子是行不通的:Sisyphus将在你完成任务之前完成任务。
你还应该记住,你拿起别人的垃圾越好,他们扔给你的垃圾就越多。
<强>附录强>
实际上,如果输入文件包含一系列格式良好的XML文档连接成一个文件,那么输入的语法实际上可以很容易地指定。这只是XML规范中添加的一条额外规则:
file ::= document+
可能修改了文档开头的XML声明是强制性的。
因此,定义您想要接受的语法可能并不太难。但编写一个准确接受这种语法的解析器仍然是一个挑战。最干净的方法可能是采用开源XML解析器并对其进行修改。
没有办法用正则表达式解析这个语法:它不是常规语言(如果你不明白这意味着什么,你不应该编写解析器,但实质上它意味着语法的定义是递归)。
但是你可以使用一些技巧。每个文档都以<?xml
开头,<?xml
唯一可以出现的地方是:(a)文档开头,(b)注释,(c)CDATA部分。注释和CDATA部分不能嵌套,所以我认为你的语言的每个实例都符合更简单的语法:
(`<?xml` (stuff | cdata | comment)* )*
其中stuff
被定义为不包含<?xml
,<![CDATA[
或<!--
)的任何内容,cdata和comment定义为XML格式。
根据这种更简单(非递归)语法解析文档足以识别文档边界,并且完成后您可以将每个文档传递给常规XML解析器。