Java XML Unmarshalling терпит неудачу на амперсанде (&), используя JAXB - PullRequest
2 голосов
/ 08 июня 2010

У меня есть следующий XML:

<?xml version="1.0" encoding="UTF-8"?>
<details>
  ...
  <address1>Test&amp;Address</address1>
  ...
</details>

Когда я пытаюсь разобрать его с помощью JAXB, выдается следующее исключение:

Caused by: org.xml.sax.SAXParseException: The reference to entity "Address" must end with the ';' delimiter.
        at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
        at org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
        at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
        at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
        at org.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
        at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEntityReference(Unknown Source)
        at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
        at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
        at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
        at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
        at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
        at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
        at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
        at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:194)

Но когда я изменил &amp; в XML на &apos;, это работает. Похоже, проблема только в амперсанде &amp;, и я не могу понять, почему.

Код для демаршалирования:

JAXBContext context = JAXBContext.newInstance("some.package.name", this.getClass().getClassLoader());
Unmarshaller unmarshaller = context.createUnmarshaller();
obj = unmarshaller.unmarshal(new StringReader(xml));

У кого-нибудь есть понимание?

РЕДАКТИРОВАТЬ: я пробовал решение, предложенное @ abhin4v ниже (т.е. добавить пробел после &amp;), но, похоже, оно тоже не работает Вот трассировка стека:

Caused by: org.xml.sax.SAXParseException: The entity name must immediately follow the '&' in the entity reference.
        at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
        at org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
        at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
        at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
        at org.apache.xerces.impl.XMLScanner.reportFatalError(Unknown Source)
        at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanEntityReference(Unknown Source)
        at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
        at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
        at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
        at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
        at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
        at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
        at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
        at com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:194)

Ответы [ 3 ]

3 голосов
/ 08 июня 2010

Я тоже столкнулся с этим. Сначала я просто заменил & amp на строку токена (AMPERSAND_TOKEN), отправил ее через JAXB, затем снова заменил амперсанд. Не идеально, но это было быстрое решение.

Второй проход Я внес много значительных изменений, поэтому не уверен, что именно решило проблему. Я подозреваю, что предоставление JAXB доступа к html dtds сделало его намного счастливее, но это всего лишь предположение и может быть специфическим для моего проекта.

НТН

3 голосов
/ 08 июня 2010

Xerces преобразует &amp; в &, а затем пытается разрешить &Address, что не удается, поскольку не заканчивается ;. Поставьте пробел между & и Address, и он должен работать. Установка пробела не будет работать, поскольку Xerces теперь попытается разрешить & и выдаст вторую ошибку, указанную в OP. Вы можете поместить тест в раздел CDATA, и Xerces не будет пытаться разрешить сущности.

1 голос
/ 08 июня 2010

Оказывается, проблема в том, что я использую фреймворк ( Mentawai framework ). Указанный XML происходит из тела POST HTTP-запроса.

Очевидно, каркас преобразует символьные сущности в теле XML, поэтому &amp; становится &, и разархиватор не может разархивировать XML.

...