【问题标题】:Parse XML with nested xml opening tags <?xml ...?> in java在 java 中使用嵌套的 xml 开始标签 <?xml ...?> 解析 XML
【发布时间】:2023-04-02 13:44:01
【问题描述】:

你能帮我解析带有嵌套&lt;?xml version="1.0" encoding="utf-8"?&gt;标签的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>  

【问题讨论】:

  • 没有简单的方法来解析它,因为它不是有效的 xml。但是看到这是一个肥皂响应,这让我想知道是什么服务给你的,看看他们是否可以修复服务会更好(或者如果你有访问权限,你是否可以修复服务?)。
  • 您可以尝试对流进行预处理,删除无效部分(例如使用正则表达式替换),然后使用常规 XML 解析器对其进行解析。我还认为您可以使用 SAX 解析器对其进行解析。
  • 我已经从soap响应中看到过几次 - 即响应中的响应 - 如果您可以在解析之前对您的响应进行html编码,使其变为&amp;lt;serviceResponse&amp;gt;等前进的道路。
  • 您没有尝试使用嵌套的 XML 声明解析 XML,因为 XML 不能包含嵌套的 XML 声明。相反,您正在尝试解析非 XML 输入。因此,您将需要一个非 XML 解析器。最好说服这些文件的供应商生成格式正确的 XML。

标签: java xml xml-parsing


【解决方案1】:

我不认为这真的是一个 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 sn-p &lt;data&gt;...&lt;/data&gt; 被创建为一个单独的 DOM 对象,然后在响应中间拼接字符串。写出整个 XML 文档对象 会导致包含 XML 声明,但如果您只是抓住 文档根节点对象 (&lt;data&gt;) 并将其写成字符串,那么它可能不会包含导致你所有这些麻烦的额外 XML 声明。

【讨论】:

  • 感谢您的回复。实际上我无法控制 xlm 响应,而且我知道它不是有效的 xml。所以我选择了 xml 预处理选项并选择了内部 xml,然后才使用 SAX 解析对其进行解析并能够检索我想要的数据:)。再次感谢。
  • 我今天下午做了一些工作后想到了一个新的解决方案,但由于它与我在这里的评论完全无关,我决定将其作为单独的答案发布。
【解决方案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 中测试了该库,但上面的代码应该可以工作!)

【讨论】:

    【解决方案3】:

    &lt;? 开头的标签是一个处理指令。 &lt;?xml...&gt; 是一个 XML 声明,只能出现在 xml 内容的开头。在 XML 正文中是不允许的。

    为什么你的皂体含有这个?您可以选择删除它吗?

    【讨论】:

    • 感谢您的回复。我不控制我收到的 xml。所以我预处理了xml然后解析它。
    【解决方案4】:

    我没有在 java 中找到任何解析器来解析这样的嵌入式 xml,因为它不是有效的 xml,我猜几乎所有的解析都会在解析之前验证 xml。所以我选择预处理 xml 的选项并选择内部 xml,然后使用 SAX 解析器解析 xml 并从 xml 中检索值。伙计们感谢您的回复。

    【讨论】:

    • 距离您的原始帖子已经过去一周了,所以您可能已经从这里开始了——但是如果您仍然对没有预处理的解析感兴趣,您应该查看我关于使用 Jsoup 的新答案.
    猜你喜欢
    • 1970-01-01
    • 2011-09-24
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-04
    • 1970-01-01
    • 2013-01-24
    相关资源
    最近更新 更多