1

我有一个带有一些我想忽略的 SOAP 标记的 XML 文件。

我正在使用 pull-parser 解析 XML 文件,但由于 SOAP 标记出现,它停止工作。

XML 文件类似于:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
  <ns1:getAllUsersListResponse xmlns:ns1="http://webservice.business.ese.wiccore.myent.com/">
  <return xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema"><![CDATA[<User>

并且在标签里面<User>有我想要解析的所有标签(我知道如何使用 pull-parser)然后

</User>]]></return>
     <return xsi:type="xs:string" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema"><![CDATA[<User>

直到

</User>]]></return>
  </ns1:getAllUsersListResponse>
</soap:Body> 
</soap:Envelope>

问题是,我知道如何解析普通标签,但我不想解析这个 Soap 标签,我想忽略 SOAP 标签!任何人都知道如何实现这一目标?

4

1 回答 1

1

不太熟悉拉解析(我通常是 SAX 人),我可能不是此类事情最权威的来源,但这里有......

我相信大多数(如果不是全部)Java 拉式解析器应该使用特定的 CDATA 节点公开 CDATA 部分(例如,我相信 StAX,相关的事件类型是XMLStreamConstants.CDATA)。因此,您需要解析文档并提取该 CDATA 部分(在 SOAP<return>元素内)并提取其内容。

该部分的内容是您感兴趣的文档,因此您希望反过来对刚刚提取的内容运行新的 pull-parse。

很抱歉,我无法提供更多帮助。希望会有其他人可以为您提供更多细节。

编辑:作为对评论的回应,您可以使用 SAX 实现这一点,如下所示(为简洁起见,省略了异常处理):

import org.xml.sax.ext.DefaultHandler2;
import org.xml.sax.helpers.XMLReaderFactory;
import org.xml.sax.XMLReader;

class MyParsingApp extends DefaultHandler2 // see note 1
{
    private boolean inCdata, parsingSubDocument;
    private String subDocument;

    public static void main (String args[])
    {
        InputStream stream = ... // see note 2

        XMLReader reader = XMLReaderFactory.createXMLReader(); // see note 3
        reader.setContentHandler (new MyParsingApp ( ));
        reader.parse (new InputSource(stream));

        parsingSubDocument = true;
        reader.parse (new InputSource(new StringReader(subDocument)));

        ...
    }

    public MyParsingApp ( )
    {
        inCdata = parsingSubDocument = false;
        subDocument = "";
    }

    @Override
    public void startCDATA() throws SAXException
    {
        inCdata = true;
    }

    @Override
    public void endCDATA() throws SAXException
    {
        inCdata = false;
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException
    {
        if (inCdata)
            subDocument += new String(ch, start, length); // see note 4
    }
}

一些重要的注意事项:

  1. 通常您会使用一个单独的类作为您的内容处理程序,可能一个用于“主”文档(包括 SOAP 元素),一个用于您的“目标”文档(在 CDATA 部分中)。我在这里没有这样做只是为了让它尽可能短。
  2. 我不确定你的 XML 是什么格式,但我假设它在InputStream这里。该类InputSource将愉快地使用 a InputStream、 aReader或 aString指定要读取的文件名。使用最适合你的东西。
  3. 您需要使用 SAX2 阅读器才能处理 CDATA 内容。您的默认 SAX 阅读器可能与 SAX2 兼容,也可能不兼容。因此,您可能需要(例如)手动创建特定 SAX2 解析器的实例。如果是这种情况,您可以在此处找到一些 SAX2 解析器的列表。
  4. 也可能有更有效的方法来做到这一点(StringBuffer/StringBuilder可能是选项)。同样,为了简单起见,我只是这样做。
  5. 我还没有实际测试过这段代码。你的旅费可能会改变。

如果您以前没有使用过 SAX,可能还值得阅读SAX 快速入门指南

于 2011-05-14T00:28:33.757 回答