DOMを使用して(jDOM経由で)StAXを使用するコードを変換しようとしています。同時に、DTDベースの検証からXSDベースの検証に移行しています。ああ、良い尺度のために、私はJAXBを方程式に導入しています:)StAXと名前空間
とにかく、暫定的な移行手順として、私はユーザーにレガシードキュメント(別名、名前空間を使用しない)を提供できるようにしたいと考えています。私はまだXSDを使って文書を検証するので、DTDは無視されます。これは、StAX(JAXBも)が名前空間のない文書を気に入らないように見えることを除いて動作します。私は(javax.xml.stream.isNamespaceAwareを使って)名前空間のサポートを無効にしようとしましたが、それは何の効果もありませんでした。明示的にドキュメントルートにxmlnsを追加することで問題が解決されたので、名前空間の問題であると確信しています。
StAX XMLEventReaderを使用してデフォルト名前空間を「導入」する方法はありますか? this approach(SAX特有)の行に沿ったものですが、StAXの場合は...
これを達成するための他のアイデアですか?
例えば、文書は次のようになります。
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.test.abstractembeddedcomponents.cid">
...
</hibernate-mapping>
私は現在、これらの文書を読むために使用していますコードは:私のテストのDTDがいるかいないで
public JaxbRoot unmarshal(InputStream stream, Origin origin) {
try {
XMLEventReader staxReader = staxFactory().createXMLEventReader(stream);
try {
return unmarshal(staxReader, origin);
}
finally {
try {
staxReader.close();
}
catch (Exception ignore) {
}
}
}
catch (XMLStreamException e) {
throw new MappingException("Unable to create stax reader", e, origin);
}
}
private XMLInputFactory staxFactory;
private XMLInputFactory staxFactory() {
if (staxFactory == null) {
staxFactory = buildStaxFactory();
}
return staxFactory;
}
@SuppressWarnings({ "UnnecessaryLocalVariable" })
private XMLInputFactory buildStaxFactory() {
XMLInputFactory staxFactory = XMLInputFactory.newInstance();
// tried with and without, no effect
//staxFactory.setProperty("javax.xml.stream.isNamespaceAware", false);
return staxFactory;
}
@SuppressWarnings({ "unchecked" })
private JaxbRoot unmarshal(XMLEventReader staxEventReader, final Origin origin) {
XMLEvent event;
try {
event = staxEventReader.peek();
while (event != null && !event.isStartElement()) {
staxEventReader.nextEvent();
event = staxEventReader.peek();
}
}
catch (Exception e) {
throw new MappingException("Error accessing stax stream", e, origin);
}
if (event == null) {
throw new MappingException("Could not locate root element", origin);
}
final Schema validationSchema;
final Class jaxbTarget;
final String elementName = event.asStartElement().getName().getLocalPart();
if ("entity-mappings".equals(elementName)) {
final Attribute attribute = event.asStartElement().getAttributeByName(ORM_VERSION_ATTRIBUTE_QNAME);
final String explicitVersion = attribute == null ? null : attribute.getValue();
validationSchema = validateXml ? resolveSupportedOrmXsd(explicitVersion) : null;
jaxbTarget = JaxbEntityMappings.class;
}
else {
validationSchema = validateXml ? hbmSchema() : null;
jaxbTarget = JaxbHibernateMapping.class;
}
final Object target;
final ContextProvidingValidationEventHandler handler = new ContextProvidingValidationEventHandler();
try {
JAXBContext jaxbContext = JAXBContext.newInstance(jaxbTarget);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
unmarshaller.setSchema(validationSchema);
unmarshaller.setEventHandler(handler);
target = unmarshaller.unmarshal(staxEventReader);
}
catch (JAXBException e) {
throw new MappingException(...);
}
return new JaxbRoot(target, origin);
}
は効果がありません。
[org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'hibernate-mapping'.]
at ...
Caused by: org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'hibernate-mapping'.
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException(ErrorHandlerWrapper.java:195)
at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.error(ErrorHandlerWrapper.java:131)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:384)
at com.sun.org.apache.xerces.internal.impl.XMLErrorReporter.reportError(XMLErrorReporter.java:318)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleStartElement(XMLSchemaValidator.java:1916)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.startElement(XMLSchemaValidator.java:705)
at com.sun.org.apache.xerces.internal.jaxp.validation.ValidatorHandlerImpl.startElement(ValidatorHandlerImpl.java:550)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.ValidatingUnmarshaller.startElement(ValidatingUnmarshaller.java:78)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(InterningXmlVisitor.java:60)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXEventConnector.handleStartElement(StAXEventConnector.java:247)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.StAXEventConnector.bridge(StAXEventConnector.java:116)
at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:394)
... 27 more
StaXの実装は? JDK組み込みですか?ウッドストックス?その他? – bmargulies
JDKが内蔵されていると思います。私は別のものを設定するために特別なことをしていません。 –
人々はいつも名前空間のないドキュメントを読むためにstaxを使います。いくつかのコードと少しのXMLを表示する必要があります。 – bmargulies