4

いくつかのコードスニペット。

jaxbアンマーシャリングを実行するJavaコーディング。非常に簡単で、オンラインのチュートリアルからコピーされています。

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を変更して、xs:string拡張子を持つsimpleContextを含める場合も正常に機能します。しかし、私はこの問題を世界中のエンティティから受けています。その中には、多くのxsdファイルにamdがたくさんあります。したがって、この問題を回避するためだけに、xmlドキュメントのすべての要素をxs:stringに基づいて作成することはできません。

イベントj2se6はapache-xercesのSchemaFactoryを使用していますが、xercesの「ignore-whitespace」機能を受け入れていないようです。(つまり、schemaFactory.setFeature())

4

2 に答える 2

4

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
于 2009-07-11T10:42:42.190 に答える
2

問題を引き起こしている特定の要素(たとえば、HashLine要素のみ)から空のコンテンツを取り除くために、非常に単純なXSLT変換を作成することをお勧めします。次に、TransformerFactory、Transformerなどを使用して、データをJAXBに渡す前に処理ステップを実行します。これにより、XSLT変換を使用してデータが「クリーンアップ」されます。ソースXMLで他の非JAXBフレンドリ構造を見つけた場合に備えて、XSLTにある種のクリーニングロジックを追加できます。

于 2009-07-11T10:59:58.737 に答える