当前位置: 首页 > 知识库问答 >
问题:

JAXB和无命名空间XML

何勇
2023-03-14

供应商提供的XML如下:

<?xml version="1.0" encoding="utf-8"?>
<Foo>
  <Bar>...</Bar>
  <Bar>...</Bar>
</Foo>

请注意,没有xmlns="…"声明,供应商也没有提供模式。这不能更改,供应商将来会继续这样发布XML。

为了生成JAXB绑定,我创建了如下模式:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://acme.com/schema"
            xmlns:tns="http://acme.com/schema"
            elementFormDefault="qualified">
    <xsd:element name="Foo">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="tns:Bar" maxOccurs="unbounded"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
    <xsd:element name="Bar">
        ...
    </xsd:element>
</xsd:schema>

请注意,我已经声明了一个或多或少有意义的命名空间(“http://acme.com/schema”),以便它可以用于元素引用等。XJC 生成以下包信息.java

@javax.xml.bind.annotation.XmlSchema(namespace = "http://acme.com/schema", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.acme.schema;

然后,我尝试解组XML文档:

JAXBContext jaxb = JAXBContext.newInstance("com.acme.schema");
Unmarshaller unmarshaller = jaxb.createUnmarshaller();
InputStream is = this.getClass().getClassLoader().getResourceAsStream("test.xml");

InputSource source = new InputSource(is);
Foo foo = (Foo) unmarshaller.unmarshal(source);

我得到的例外是:

javax.xml.bind.UnmarshalException: unexpected element (uri:"", local:"Foo"). Expected elements are <{http://acme.com/schema}Foo>,...>

显然,这是因为XML元素属于一个空的名称空间,而JAXB类有一个非空的名称空间。

有没有办法伪造一个XML名称空间(可能是在XML解析期间),以便JAXB能够识别元素并成功绑定它们?SAX/StAX解决方案比DOM更受欢迎,因为XML文档可能相当大。

共有1个答案

东门阳飇
2023-03-14

首先,我不推荐所有这些。与第三方API集成非常复杂,而且不会增加额外的复杂性。为什么要费心添加命名空间?我不知道你能从中得到什么。想想能继承你的代码库的幸运儿。他们会看到名称空间的添加,但不知道您为什么要这样做。

我甚至会更进一步,建议完全避免使用架构,只使用带注释的POJO。所有这些步骤都只是增加了复杂性,构建步骤等。

然而,如果您下定决心,这似乎是XSL转换的典型情况。您可以找到一个非常容易添加名称空间的XSL转换,比如这个问题,那么将您的转换连接到JAXB就很简单了...

private static Foo unmarshalDocument(InputStream xslStream, InputStream xmlStream) throws Exception {
    StreamSource stylesource = new StreamSource(xslStream); 
    StreamSource inputStream = new StreamSource(xmlStream);
    Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesource);
    JAXBResult result = new JAXBResult(context);
    transformer.transform(inputStream, result);
    return (Foo) result.getResult();
}
 类似资料:
  • 我试图从通过JAXB生成的类序列化XML。 班级: 文件“package-info.java”: 编组器(简化,无需错误处理): 此代码生成: 我期待这样的事情: 我有一个类似的代码并且工作正常,但是我不明白为什么这个代码不显示命名空间。有线索吗?谢谢!

  • 我有情况, 有一个sample.xsd(旧版本-没有命名空间)。为同一个XSD文件使用XJC生成JAXB类。我得到了一个使用JAXB类基于XSD解封XML数据文件的示例。sample.xsd文件已更改(新版本-添加的命名空间)。再次为新的XSD文件使用XJC生成JAXB类。该示例已更新,现在可以用于新的XSD文件 现在我有一个情况,我正在获取基于旧XSD的XML数据文件,我想使用更新的示例文件来解

  • 我有一个为安全令牌构建的XML。这些包含基于WS-Trust的名称空间,但是当我解组这个XML以创建< code > RequestSecurityTokenResponseCollection 对象时,它用< code>ns1 、< code>ns2 、< code>ns3等名称空间替换了这些名称空间。 是否有一种方法可以在不更改输入XML中的名称空间和名称空间前缀的情况下解组XML? 这是我一

  • 我的代码如下: 我怎样才能让它工作?如果我的xml标记有一些相关元素,如上面的“xmlns”,则JAXB解组器会抛出异常。 这是我第一次这么做,所以我对JAXB、解编等都一无所知。我在苦苦挣扎任何帮助都是好的。 编辑StackTrace:

  • 当我试图使用包含名称空间的JAXB将xml转换为Java对象时,会发生错误。 示例示例:' Zeta Walnes ` 我需要忽略名称空间

  • Im使用jaxb生成XML请求。下面是所有的代码细节。我也尝试过包信息的东西,但它不适合我。就像我想在每个对象XML标记上添加命名空间一样。 希望你们明白我的意思。我是做错了什么还是遗漏了什么?或者这种事情在JAXB Java中是可能的。 所需输出 我得到了什么 下面是我的JAXB父Java对象类 下面是我的内部JAXB对象Java类 下面是我的AcctChgRecType JAXB对象类