Игнорировать теги SOAP в файле XML - PullRequest
1 голос
/ 14 мая 2011

У меня есть файл XML с некоторыми тегами SOAP, которые я хочу игнорировать.

Я анализировал XML-файл с помощью pull-parser, но он перестал работать, так как появились эти теги 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! Кто-нибудь знает, как этого добиться?

1 Ответ

1 голос
/ 14 мая 2011

Не слишком хорошо разбираясь в парсинге (я, как правило, парень SAX), я, вероятно, не самый авторитетный источник в таких вещах, но здесь ...

Я полагаю, что большинство (если не все) парсеры Java Pull должны предоставлять разделы CDATA, используя определенный узел CDATA (я считаю, что в StAX, например, соответствующий тип события XMLStreamConstants.CDATA). Таким образом, вы захотите проанализировать ваш документ и извлечь этот раздел CDATA (внутри элемента SOAP <return>) и извлечь его содержимое.

Содержимое этого раздела - это документ, который вас интересует, так что вы, в свою очередь, захотите выполнить новый разбор содержимого, которое вы только что извлекли.

Извините, я не могу помочь. Надеюсь, что найдется кто-то еще, кто сможет рассказать вам подробности подробнее.

РЕДАКТИРОВАТЬ: в ответ на комментарии, вы можете достичь этого, используя 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 с радостью будет использовать InputStream, Reader или String, указывающие имя файла для чтения. Используйте то, что вам больше подходит.
  3. Вам понадобится ридер SAX2, чтобы иметь возможность обрабатывать содержимое CDATA. Ваш читатель SAX по умолчанию может или не может быть SAX2-совместимым. Таким образом, вам может понадобиться (например) вручную создать экземпляр определенного синтаксического анализатора SAX2. Вы можете найти список некоторых парсеров SAX2 здесь , если это так.
  4. Возможно, есть и более эффективные способы сделать это (StringBuffer / StringBuilder могут быть вариантами). Опять же, я просто делаю это так для простоты.
  5. Я на самом деле не проверял этот код. Ваш пробег может отличаться.

Если вы ранее не использовали SAX, возможно, стоит также ознакомиться с Краткое руководство по SAX .

...