替换Unmarshal上删除的命名空间详细信息

时间:2014-02-04 12:16:36

标签: java xml jaxb unmarshalling

我有业务要求以尽可能轻量级的形式从类(在架构中定义)生成XML。为此,我从xml中删除了所有名称空间信息。

示例架构:

<xs:schema xmlns="http://aschema/" 
           xmlns:xs="http://www.w3.org/2001/XMLSchema" 
           targetNamespace="http://aschema/" 
           elementFormDefault="qualified" 
           attributeFormDefault="unqualified">

  <xs:element name="Test" type="TestType"/>
  <xs:complexType name="TestType">
    <xs:sequence>
      <xs:element name="test" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

生成Test类:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "TestType", propOrder = {
    "test"
})
@XmlRootElement(name = "Test")
public class Test {

    @XmlElement(required = true)
    protected String test;

    /**
     * Gets the value of the test property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getTest() {
        return test;
    }

    /**
     * Sets the value of the test property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setTest(String value) {
        this.test = value;
    }

}

Marshals to(我可以解释如果你愿意,但我认为这会使问题变得混乱 - 如果要求的话,很乐意添加):

<Test><test>Hello World!</test></Test>

现在我想要解组它。我得到(并不奇怪):

javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"Test"). Expected elements are <{http://aschema/}Test>

我是否可以通过某种方式为我的解组过程定义在遇到此问题时要使用的内容?

我无法更改架构 - 它是行业标准。

我无法更改Test对象 - 它是从架构生成的。

我发现的所有对此错误的引用似乎都指向java类的更改或模式的更改 - 我不能做这些事情中的任何一个。

请注意,我的Test类是尝试创建Minimal, Complete, Tested and Readable example。我想要解组的真实对象要复杂得多。

1 个答案:

答案 0 :(得分:0)

像往常一样 - 一旦我发布了问题,就会出现一个解决方案 - 好像是魔术师。这就是StackOverflow。

来自JAXB unmarshal with declared type does not populate the resulting object with data

public class NamespaceFilter extends XMLFilterImpl {

  private static final String NAMESPACE = "http://aschema/";

  @Override
  public void endElement(String uri, String localName, String qName) throws SAXException {
    super.endElement(NAMESPACE, localName, qName);
  }

  @Override
  public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
    super.startElement(NAMESPACE, localName, qName, atts);
  }

}

...

  // Create the XMLFilter
  XMLFilter filter = new NamespaceFilter();

  // Set the parent XMLReader on the XMLFilter
  SAXParserFactory spf = SAXParserFactory.newInstance();
  SAXParser sp = spf.newSAXParser();
  XMLReader xr = sp.getXMLReader();
  filter.setParent(xr);

  // Set UnmarshallerHandler as ContentHandler on XMLFilter
  Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
  UnmarshallerHandler unmarshallerHandler = unmarshaller.getUnmarshallerHandler();
  filter.setContentHandler(unmarshallerHandler);

  // Parse the XML
  filter.parse(new InputSource(r));
  //Object result = unmarshallerHandler.getResult();  
  T t = (T) unmarshallerHandler.getResult();