Атрибуты XML без пробелов - PullRequest
0 голосов
/ 16 декабря 2011

Я использовал JAXB для создания класса для следующей схемы (используется в веб-сервисе):

<xs:complexType name="ExceptionType">
        <xs:attribute name="errorCode" type="xs:positiveInteger" use="required"/>
        <xs:attribute name="outcomeType" use="required">
            <xs:simpleType>
                <xs:restriction base="xs:token">
                    <xs:enumeration value="rejectFile"/>
                    <xs:enumeration value="rejectSubmission"/>
                    <xs:enumeration value="continue"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
</xs:complexType>

Хотя фактический XML, который они отправят, равен

<Exception errorCode="1503"outcomeType="continue">

(без пробела с "1503" и resultType).

Прямо сейчас я заменяю <Exception errorCode="(\d*)"outcomeType на <Exception errorCode="\1" outcomeType во всем XML-ответе перед передачей его в JAXB unmarshaller, и это работает, но мне интересно, будут ли другие "XML-ответы" иметь эту "ошибку".
Есть ли более простой способ, позволяющий JAXB принимать теги XML с этой ошибкой attr1="value"attr2? Или, может быть, использовать какой-то пользовательский XMLFilterImpl?

Ответы [ 3 ]

3 голосов
/ 16 декабря 2011

Есть ли более простой способ, чтобы JAXB мог принимать теги XML с этой ошибкой attr1 = "value" attr2?

Нет, потому что это не ошибка.

XML, содержащий attr1="value"attr2, неправильно сформирован, поэтому JAXB не сможет его проанализировать и выдаст исключение, указывающее на фатальную невосстановимую ошибку.

Если вы ожидаете XML-ish данные такого рода, и вы не можете их контролировать (вы получаете их от третьей стороны), тогда ваше решение кажется ОК.Однако, если бы я был вами, я бы связался с этой третьей стороной и сказал бы им, что они извергают недопустимый XML, и это не слишком профессионально.

Альтернативой замене строк регулярными выражениями может быть что-то вроде этого (но это не совсем просто):

public String toWellFormed(String xml) throws IOException, SAXException {             
  StringBuilder sb = new StringBuilder(xml);                                                 

  XMLReader reader = XMLReaderFactory.createXMLReader();                                     
  reader.setContentHandler(null);                                                            
  reader.setErrorHandler(null);                                                              

  boolean threw = true;                                                                      
  while (threw)                                                                              
    try {                                                                                    
      reader.parse(new InputSource(new StringReader(sb.toString())));                        
      threw = false;                                                                         
    } catch (SAXParseException ex) {                                                         
      if (ex.getMessage().contains("must be followed by either attribute specifications")) {
        threw = true;
        int line = ex.getLineNumber();                                                       
        int column = ex.getColumnNumber();                                                   
        sb.insert(line * column - 1, ' ');                                                                                                            
      } else                                                                                 
        throw ex;                                                                            
    }                                                                                        

  return sb.toString();                                                                      
}                       

String malformedXml = "<test a='a'b='b'c='c'/>";  
String wellFormedXml = toWellFormed(malformedXml);
"<test a='a'b='b'c='c'/>".equals(wellFormedXml);

JAXB Unmarshaller должен уметь обрабатывать wellFormedXmlпосле процесса.

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

Обратите внимание, что я явно установил обработчик ошибок читателя и содержимого на null.Это потому, что из-за искаженного XML они никогда не называются;читатель рано потерпит неудачу, потому что это фатальная, невосстановимая ошибка.Это, конечно, очень плохо для нас, потому что если документ содержит 10 ошибок, как вы описали, тогда мой метод анализирует XML 10 раз, пока не найдет каждую ошибку.Мне неизвестен XML-анализатор в JDK, который бы сообщал об ошибках форматирования и продолжал синтаксический анализ (сообщая о каждой ошибке во время процесса).

Используя правильный ErrorHandler, вы могли быобрабатывать предупреждения и ошибки изящно, однако фатальные ошибки не могут быть обработаны даже с ErrorHandler (после вызова метода fatalError обработка останавливается).

Использование XMLFilterреализация также не поможет вам, потому что если вы просто используете класс XMLFilterImpl по умолчанию, который перенаправляет все его вызовы делегату XMLReader, то вы столкнетесь с той же проблемой, что и раньше: при первой ошибке обработка останавливается.На самом деле, если вы хотите что-то реализовать, то реализуйте интерфейс XMLReader напрямую (XMLFilter добавляет только методы setParent и getParent - плохой дизайн, если вы спросите меня).Но реализация XMLReader, которая может анализировать искаженный XML, вероятно, будет утомительной.

1 голос
/ 16 декабря 2011

Это недопустимый xml (без пробела между значением attr и следующим attr), и анализатор всегда будет терпеть неудачу. Я думаю, вам придется управлять им так, как вы это делаете в настоящее время, или исправить это в самом источнике.

0 голосов
/ 16 декабря 2011

Ну, JAXB просто следует ограничениям XML. Если места нет, оно не будет проверено. Может быть, отключить проверку? Это может работать через это.

...