Tôi sử dụng Jaxb2 và Spring. Tôi đang cố gắng để unmarshal một số XML được gửi bởi 2 của khách hàng của tôi.Jaxb bỏ qua không gian tên trên unmarshalling
Cho đến nay, tôi chỉ phải xử lý một khách hàng mà gửi một số xml như thế này:
<foo xmlns="com.acme">
<bar>[...]</bar>
<foo>
được ràng buộc với một POJO như thế này:
@XmlType(name = "", propOrder = {"bar"})
@XmlRootElement(name = "Foo")
public class Foo {
@XmlElement(name = "Bar")
private String bar;
[...]
}
tôi phát hiện ra rằng trước nhà phát triển đã mã hóa không gian tên trong unmarshaller để làm cho nó hoạt động.
Bây giờ, khách hàng thứ hai gửi cùng một XML nhưng thay đổi không gian tên!
<foo xmlns="com.xyz">
<bar>[...]</bar>
<foo>
Rõ ràng, unmarshaller không unmarshall vì nó hy vọng một số {com.acme}foo
thay vì {com.xyz}foo
. Thật không may, yêu cầu khách hàng thay đổi XML không phải là một lựa chọn.
gì tôi đã cố gắng:
1) Trong application-context.xml
, tôi đã tìm kiếm cho một cấu hình mà sẽ cho phép tôi bỏ qua không gian tên nhưng không thể tìm thấy một:
<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="packagesToScan">
<list>
<value>com.mycompany.mypkg</value>
</list>
</property>
<property name="marshallerProperties">
<map>
<entry key="???"><value type="java.lang.Boolean">false</value></entry>
</map>
</property>
</bean>
có vẻ như các tùy chọn khả dụng duy nhất là các tùy chọn được liệt kê trong Javadoc của Jaxb2Marshaller:
/**
* Set the JAXB {@code Marshaller} properties. These properties will be set on the
* underlying JAXB {@code Marshaller}, and allow for features such as indentation.
* @param properties the properties
* @see javax.xml.bind.Marshaller#setProperty(String, Object)
* @see javax.xml.bind.Marshaller#JAXB_ENCODING
* @see javax.xml.bind.Marshaller#JAXB_FORMATTED_OUTPUT
* @see javax.xml.bind.Marshaller#JAXB_NO_NAMESPACE_SCHEMA_LOCATION
* @see javax.xml.bind.Marshaller#JAXB_SCHEMA_LOCATION
*/
public void setMarshallerProperties(Map<String, ?> properties) {
this.marshallerProperties = properties;
}
2) Tôi cũng đã cố gắng để cấu hình unmarshaller trong các mã:
try {
jc = JAXBContext.newInstance("com.mycompany.mypkg");
Unmarshaller u = jc.createUnmarshaller();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(false);//Tried this option.
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(xmlFile.toFile());
u.unmarshal(new DOMSource(doc));
return (Foo)u.unmarshal(new StreamSource(xmlFile.toFile()));
} catch (ParserConfigurationException | SAXException | IOException | JAXBException e) {
LOGGER.error("Erreur Unmarshalling CPL");
}
3) hình thức khác nhau với một SAXParser:
try {
jc = JAXBContext.newInstance("com.mycompany.mypkg");
Unmarshaller um = jc.createUnmarshaller();
final SAXParserFactory sax = SAXParserFactory.newInstance();
sax.setNamespaceAware(false);
final XMLReader reader = sax.newSAXParser().getXMLReader();
final Source er = new SAXSource(reader, new InputSource(new FileReader(xmlFile.toFile())));
return (Foo)um.unmarshal(er);
}catch(...) {[...]}
một này hoạt động! Nhưng vẫn còn, tôi muốn có thể autowire Unmarshaller mà không cần conf này xấu xí mọi lúc.