使用Java解析带有嵌套的XML开标签<?xml ...?>

3

您能否帮我解析具有嵌套的<?xml version="1.0" encoding="utf-8"?>标签的XML。 当我尝试解析此XML时,出现了解析错误。

<?xml version="1.0" encoding="utf-8"?>      
<soap>
            <soapenvBody>
                <serviceResponse>
                    <?xml version="1.0" encoding="UTF-8"?>
                    <data>
                        <respCode>0</respCode>
                    </data>
                </serviceResponse>
            </soapenvBody>
        </soap>  

2
没有简单的方法来解析它,因为它不是有效的XML。但是看到它是一个SOAP响应,让我想知道是哪个服务提供给你的,如果有可能的话,最好是看看他们能否修复服务(或者如果你有权限的话,是否可以修复服务?)。 - undefined
你可以尝试预处理流,删除无效部分(例如使用正则表达式替换),然后使用常规的 XML 解析器进行解析。我还认为你也可以使用 SAX 解析器来解析它。 - undefined
我在从 SOAP 响应中几次看到过这种情况,即一个响应内包含另一个响应。如果你可以在解析之前对响应进行 HTML 编码,将其变成类似 &lt;serviceResponse&gt; 的形式,那就是正确的方式。 - undefined
你不是在尝试解析带有嵌套XML声明的XML,因为XML本身不能包含嵌套的XML声明。相反,你正在尝试解析非XML格式的输入。所以你需要使用一个非XML解析器。最好的做法是劝说文件供应商生成符合规范的XML文件。 - undefined
4个回答

2

我想到一个处理HTML的解析器可能能够做你想要的事情。由于与严格的XML相比,HTML往往是一团糟,因此HTML解析器通常更容错。快速搜索找到了jsoup。使用大致以下代码,我能够从上面的示例XML中获取respCode

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

String data = "your xml goes here";
Document doc = Jsoup.parse(data);
String respCodeRaw = doc.select("respCode").first().text();
int respCode = Integer.valueOf(respCodeRaw);

我实际上在Clojure repl中测试了该库,但上面的代码应该可以工作!


2
我认为这并不是一个Java问题。在XML主体中有第二个XML声明是非法的,因此我认为您将无法让任何XML解析器解析它。如果您可以控制XML(看起来您正在生成它以存储响应),那么您可以尝试使用CDATA包装内部XML文档:
<?xml version="1.0" encoding="utf-8"?>     
<soap>
    <soapenvBody>
        <serviceResponse>
          <![CDATA[
              <?xml version="1.0" encoding="UTF-8"?>
              <data>
                  <respCode>0</respCode>
              </data>
          ]]>
        </serviceResponse>
    </soapenvBody>
</soap>

编辑:

我认为你最可能根本不想在响应中包含额外的XML声明。你能控制创建响应的代码吗?我的猜测是,XML片段<data>...</data>被创建为单独的DOM对象,然后将字符串拼接在响应的中间。将整个XML文档对象写出会导致包含XML声明,但如果你只获取文档根节点对象<data>)并将其作为字符串输出,则可能不会包含引起您所有麻烦的额外XML声明。


谢谢回复。实际上,我无法控制XML响应,并且我知道它不是有效的XML。所以我选择了XML预处理选项,并选择了仅内部XML,然后使用SAX解析器解析它,并成功地检索到了我想要的数据:)。再次感谢。 - undefined
今天下午我做了一些工作后,我想到了一个新的解决方案,但由于它与我在这里的评论完全无关,所以我决定将其作为一个单独的答案发布。 - undefined

0
一个以<?开头的标签是一个处理指令。 <?xml...> 是一个XML声明,只能出现在xml内容的开头。它不允许出现在XML主体中。
为什么你的soap主体包含这个?你有删除它的选项吗?

谢谢回复。我无法控制接收到的XML,所以我对XML进行了预处理然后解析它。 - undefined

0

我在Java中没有找到任何解析器来解析这样的嵌入式XML,因为它不是一个有效的XML,我猜几乎所有的解析器都会在解析之前验证XML。所以我选择了预处理XML并选择了内部XML,然后使用SAX解析器解析XML并从中提取值。谢谢大家的回复。


1
你发表原始帖子已经有一周了,所以你可能已经对此不再关注了——但如果你仍然对不使用预处理进行解析感兴趣,你应该看看我的新答案,关于使用Jsoup的。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接