【问题标题】:JAXB Namespace issueJAXB 命名空间问题
【发布时间】:2014-06-07 17:13:04
【问题描述】:

这个问题是针对 JAXB 命名空间上的 Blaise Doughan 先生提出的

我有情况,

有一个 sample.xsd(旧版本 - 没有命名空间)。使用 XJC 为同一 XSD 文件生成 JAXB 类。我有一个示例,它使用 JAXB 类基于 XSD 解组 XML 数据文件。 sample.xsd 文件已更改(新版本 - 添加了命名空间)。再次使用 XJC 为新的 XSD 文件生成 JAXB 类。示例已更新,现在可以用于新的 XSD 文件

现在我遇到了一种情况,我正在获取基于旧 XSD 的 XML 数据文件,我想使用更新后的示例文件来解组旧的 XML 数据。

我可以看到一个解决方案,生成两个对象工厂,一个带有命名空间,一个没有命名空间。我们可以这样做吗?如果是这样,我可以根据我获得的 XML 数据使用适当的对象工厂。

或者想知道,我怎样才能为两个 XSD 文件生成 JAXB 类,但 XJC 没有生成,它显示错误 - 在模式或绑定文件中未检测到更改 - 跳过源生成。

我可以在新的对象工厂上创建一个包装器,以便它可以同时处理这两者吗?

请为我提供一些解决方案,以便我可以使用新的 JAXB 类解组旧文件。可以

【问题讨论】:

    标签: namespaces jaxb


    【解决方案1】:

    应用命名空间

    如果输入 XML 没有命名空间,您可以利用 SAX XMLFilter 应用命名空间。

    import org.xml.sax.*;
    import org.xml.sax.helpers.XMLFilterImpl;
    
    public class NamespaceFilter extends XMLFilterImpl {
    
        private static final String NAMESPACE = "http://www.example.com/customer";
    
        @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);
        }
    
    }
    

    进行解组

    利用 JAXB 的 UnmarshallerHandler 作为 ContentHandler 完成解组

    import javax.xml.bind.*;
    import javax.xml.parsers.*;
    import org.xml.sax.*;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            // Create the JAXBContext
            JAXBContext jc = JAXBContext.newInstance(Customer.class);
    
            // 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 = jc.createUnmarshaller();
            UnmarshallerHandler unmarshallerHandler = unmarshaller
                    .getUnmarshallerHandler();
            filter.setContentHandler(unmarshallerHandler);
    
            // Parse the XML
            InputSource xml = new InputSource("src/blog/namespace/sax/input.xml");
            filter.parse(xml);
            Customer customer = (Customer) unmarshallerHandler.getResult();
    
            // Marshal the Customer object back to XML
            Marshaller marshaller = jc.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(customer, System.out);
        }
    
    }
    

    更多信息

    【讨论】:

    • 嗨,我按照你的建议做了。为输出应用了命名空间,我们不会得到命名空间。但我发现了另一个问题;我的问题在 2 cmets 以下,请求同时阅读。旧模式没有命名空间。新模式有命名空间,它甚至导入另一个模式。当我运行该示例时,采用没有命名空间的 XML 输出并尝试在应用命名空间过滤器后使用具有命名空间的 JAXB 对象进行编组,我得到以下输出。我的意图是拥有与命名空间相同的完整 XML 输出。但我不明白,我只得到两行以下。
    • [无法放置实际的架构 URL - 它不允许我放置 http url,因此 intest 保留 xxxxx) Comment1 旧的 XML 架构是 此架构没有命名空间
    • 评论 2 命名空间添加到架构,甚至一个导入另一个架构。
    • 嗨 - 你能帮忙解决我的问题吗
    猜你喜欢
    • 2018-05-01
    • 1970-01-01
    • 2015-02-01
    • 1970-01-01
    • 2015-04-21
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多