【问题标题】:JAXB adding namespace to parent but not to the child elements containedJAXB 将命名空间添加到父元素而不是包含的子元素
【发布时间】:2010-05-31 12:54:16
【问题描述】:

我组装了一个 XSD 并使用 JAXB 从中生成类。

这是我的 XSD-

myDoc.xsd :
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="http://www.mydoc.org"
       targetNamespace="http://www.mydoc.org"
       xmlns:xs="http://www.w3.org/2001/XMLSchema"
       xmlns:mtp="http://www.mytypes.com" elementFormDefault="qualified">

<xs:import namespace="http://www.mytypes.com" schemaLocation="mytypes.xsd" />
<xs:element name="myDoc">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="crap" type="xs:string"/>
      <xs:element ref="mtp:foo"/>
      <xs:element ref="mtp:bar"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

mytypes.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.mytypes.com"
       xmlns="http://www.mytypes.com"
       xmlns:tns="http://www.mytypes.com"
       xmlns:xs="http://www.w3.org/2001/XMLSchema"
       attributeFormDefault="qualified" elementFormDefault="qualified">


  <xs:element name="foo" type="tns:Foo"/>
  <xs:element name="bar" type="tns:Bar"/>
  <xs:element name="spam" type="tns:Spam"/>

  <xs:simpleType name="Foo">
    <xs:restriction base="xs:string"></xs:restriction>
  </xs:simpleType>

  <xs:complexType name="Bar">
    <xs:sequence>
      <xs:element ref="spam"/>
    </xs:sequence>
  </xs:complexType>

  <xs:simpleType name="Spam">
    <xs:restriction base="xs:string" />
  </xs:simpleType>

</xs:schema>

编组的文件是-

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<myDoc xmlns:ns2="http://www.mytypes.com">
  <crap>real crap</crap>
  <ns2:foo>bleh</ns2:foo>
  <ns2:bar>
    <spam>blah</spam>
  </ns2:bar>
</myDoc>

请注意,&lt;spam&gt; 元素使用默认命名空间。我希望它使用 ns2 命名空间。架构 (mytypes.xsd) 表示 &lt;spam&gt; 包含在 &lt;bar&gt; 中,在 XML 实例中绑定到 ns2 命名空间。

我已经为此烦恼了一个多星期,我希望ns2 前缀出现在&lt;spam&gt; 中。我该怎么办?

必填:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<myDoc xmlns:ns2="http://www.mytypes.com">
  <crap>real crap</crap>
  <ns2:foo>bleh</ns2:foo>
  <ns2:bar>
    <ns2:spam>blah</ns2:spam><!--NS NS NS-->
  </ns2:bar>
</myDoc>

【问题讨论】:

    标签: java xml xsd jaxb marshalling


    【解决方案1】:

    检查生成的类中的字段是否缺少@XmlElement 注释,如果存在,它们是否缺少命名空间属性。这两个是必须的,以便针对您编组的 xml 中的每个元素获取命名空间前缀

    【讨论】:

      【解决方案2】:

      我已尝试重现您的问题,但在这里它工作正常:当编组垃圾邮件元素时,确实获得了 ns2 命名空间。

      我的编组代码:

          Bar bar = new Bar();
          bar.setSpam("s");
      
          MyDoc myDoc = new MyDoc();
          myDoc.setBar(bar);
      
          JAXBContext context = JAXBContext.newInstance("org.mydoc");
      
          Marshaller marshaller = context.createMarshaller();
          marshaller.marshal(myDoc, System.out);
      

      输出:

      <?xml version="1.0" encoding="UTF-8" standalone="yes"?><myDoc xmlns="http://www.mydoc.org" xmlns:ns2="http://www.mytypes.com"><ns2:bar><ns2:spam>s</ns2:spam></ns2:bar></myDoc>
      

      我的 JAXB 版本:

      xjc version "JAXB 2.1.3 in JDK 1.6"
      JavaTM Architecture for XML Binding(JAXB) Reference Implementation, (build IBM JAXB 2.1.3 in JDK 1.6)
      

      编辑:

      Bar.java 类确实有以下注解:

      @XmlElement(required = true)
      protected String spam;
      

      XmlElement 还有一个命名空间属性。 Javadoc:http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/XmlElement.html#namespace()

      默认情况下,它将查看 com.mytypes 包中的 @XmlSchema 注释。您是否删除了 @XmlSchema 注释和/或 package-info.java 文件?

      【讨论】:

      • 我将 JaxB-2.1.11 与 JDK1.5 一起使用。我还没有手动编辑生成的类和 package-info.java 文件。 Bar.java 注释为 - @XmlType(name = "Bar" namespace="mytypes.com" propOrder = {"spam"}) package-info.java 包含 @XmlSchema(namespace="mydoc.org", elementFormDefault=XmlNsForm .合格)
      • 有趣的是,我可以对文档进行编组,然后将其解组。 AFAIU,XML 实例声明 属于 null 命名空间,不应找到其定义
      【解决方案3】:

      package-info.java 没有被我的构建系统编译,因此 elementFormDefault="qualified" 并且目标命名空间没有进入 Jaxb 注释类。

      如果您看到此行为,请确保您的 package-info.java 正在编译为 .class 文件并且位于您的类路径中。

      干杯。

      【讨论】:

        【解决方案4】:

        如果您使用 Maven 2 和以下 jaxws-maven-plugin 构建,也会出现此错误。

         <groupId>org.codehaus.mojo</groupId>
         <artifactId>jaxws-maven-plugin</artifactId>
        

        并且由于某种原因已经为 java 1.5 配置了 maven-compiler-plugin。将目标/源设置为 1.6 可以解决问题。

         <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.6</source>
                <target>1.6</target>
                </configuration>
         </plugin>
        

        如果您知道原因,请随时发表评论。

        【讨论】:

          【解决方案5】:

          你可以在你的 package-info.java 中指定它 在@XmlSchema 注释中。

          elementFormDefault=XmlNsForm.QUALIFIED
          

          示例 package-info.java

          @XmlSchema(
              namespace="desiredNamespace",   
              // If qualified namespace will be added to all elements
              elementFormDefault = XmlNsForm.QUALIFIED,
              // If qualifies namespace will be added to all attributes
              attributeFormDefault = XmlNsForm.UNQUALIFIED,
              xmlns = {   
                  @XmlNs(prefix = "xsd", namespaceURI = "desiredNamespace"),
                  @XmlNs(prefix = "xsi", namespaceURI = "anotherLink"),
              }
          )
          

          【讨论】:

            【解决方案6】:

            您是否检查过您的代码,您已将 ElementType 指定为“垃圾邮件”,但在 bar 下被称为“垃圾邮件”。这个大写的“S”和小写的“s”在你的代码中,如果不打扰,我很抱歉,但如果真的打扰,你可能需要正确使用它。尝试在任何地方使用“垃圾邮件”并检查一下 na..

            -- 抱歉,我是 xslt、xml、xsd 和其他东西的初学者,对 JAXB 一无所知。但一般来说,当我们阅读有关使用 Xsd 编写 xml 文档的信息时,我们也会始终注意区分大小写。

            对不起,如果这个答案不能解决你的问题。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2013-06-03
              • 1970-01-01
              • 1970-01-01
              • 2013-03-19
              • 1970-01-01
              • 2019-11-17
              • 2017-11-27
              • 2013-01-10
              相关资源
              最近更新 更多