проверка JAXB, но пробелы не игнорируются - PullRequest
4 голосов
/ 11 июля 2009

некоторые фрагменты кода.

Java-кодирование, выполняющее Jaxb Unmarshaling. довольно просто, скопировано из учебников онлайн.

JAXBContext jc = JAXBContext.newInstance( "xmlreadtest" );
Unmarshaller u = jc.createUnmarshaller();

// setting up for validation.
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
StreamSource schemaSource =  new StreamSource(ReadXml.class.getResource("level.xsd").getFile());
Schema schema = schemaFactory.newSchema(schemaSource);
u.setSchema(schema);

// parsing the xml
URL url = ReadXml.class.getResource("level.xml");
Source sourceRoot = (Source)u.unmarshal(url);

Проблемный элемент из XML-файла. Элемент содержит только игнорируемые пробелы. Он плохо отформатирован, как показано точно , как его нашли в файле.

<HashLine _id='FI6'
ppLine='1'
origLine='1'
origFname='level.cpp'>
</HashLine>

Элемент xsd, который описал этот элемент.

<xs:element name="HashLine">
  <xs:complexType>
    <xs:attribute name="origLine" type="xs:NMTOKEN" use="required" />
    <xs:attribute name="origFname" type="xs:string" use="required" />
    <xs:attribute name="_id" type="xs:ID" use="required" />
    <xs:attribute name="ppLine" type="xs:NMTOKEN" use="required" />
  </xs:complexType>
</xs:element>

ошибка

[org.xml.sax.SAXParseException: cvc-complex-type.2.1: Element 'HashLine' must have no character or element information item [children], because the type's content type is empty.]

Я подтвердил, что ошибка исходит от этого элемента.

Загружается нормально, без проверки. Но мне нужно использовать валидацию, так как я собираюсь вносить значительные изменения и дополнения в приложение, и я должен быть уверен, что все будет правильно маршалировать / демаршалировать.

Это также хорошо работает, если я изменю complexType, чтобы включить simpleContext с расширением xs: string. Но я получаю эту проблему от всех сущностей, которых много, и много в файлах xsd. Таким образом, невозможно обойти каждый элемент в документах xml на xs: string, чтобы обойти эту проблему.

Событие, хотя j2se 6 использует SchemaFactory из apache-xerces, похоже, оно не принимает функцию ignore-whitespace из from xerces. (т.е. schemaFactory.setFeature ())

Ответы [ 2 ]

4 голосов
/ 11 июля 2009

Вы можете использовать StAX API для фильтрации пустых блоков символов перед проверкой с использованием EventFilter :

class WhitespaceFilter implements EventFilter {
  @Override
  public boolean accept(XMLEvent event) {
    return !(event.isCharacters() && ((Characters) event)
        .isWhiteSpace());
  }
}

Это может быть использовано для переноса ввода:

// strip unwanted whitespace
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
XMLEventReader eventReader = inputFactory
    .createXMLEventReader(ReadXml.class.getResourceAsStream("level.xml"));
eventReader = inputFactory.createFilteredReader(eventReader,
    new WhitespaceFilter());

// parsing the xml
Source sourceRoot = (Source) unmarshaller.unmarshal(eventReader);

//TODO: proper error + stream handling
2 голосов
/ 11 июля 2009

Я бы предложил написать очень простое XSLT-преобразование, чтобы убрать пустой контент из тех конкретных элементов, которые вызывают проблему (например, только элементы HashLine). Затем поместите шаг обработки, прежде чем передавать данные через JAXB, используя TransformerFactory, Transformer и т. Д., Который «очищает» данные с помощью преобразования XSLT. Вы можете добавить в XSLT своего рода логику очистки для случаев, когда вы найдете другие не-JAXB дружественные структуры в исходном XML.

...