java - 如何使用 JAXB 编码消除元素/属性中自动生成的命名空间前缀

标签 java xml jaxb marshalling

问题

如何在使用 JAXB 编码时消除出现在所有元素和属性上的自动生成的命名空间前缀

我已经展示了编码后的当前 XML 输出和预期输出。

详情

我正在使用 JDK 1.6 更新 21 提供的默认 JaxB 实现 (Metro)。

我的 XSD 文件如下所示。我使用 xjc 为此 XSD 生成 Java 类,我不想添加/更改任何 生成的 Java 类中的注释,以便我可以继续使用 xjc。

在代码中,这就是我编码的方式......我使用 ObjectFactory 等创建 MYJAVAOBJECTREE 的地方......

    JAXBContext jcDXD = JAXBContext.newInstance(MDASJ.class);
    QName qn=new QName(XMLDataFormat.XML_ROOT_NAME);
    marshallerDXD = jcDXD.createMarshaller();
    marshallerDXD.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    marshallerDXD.setProperty(Marshaller.JAXB_ENCODING, "ISO-8859-1");
    marshallerDXD.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.theronyx.com/mdasj/xmldata mdasj-data.xsd");
    jaxbElementDXD = new JAXBElement<MDASJ>(qn, MDASJ.class, MYJAVAOBJECTTREE);
    marshallerDXD.marshal(jaxbElementDXD, System.out);

XSD 文件

    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
                targetNamespace="http://www.theronyx.com/mdasj/xmldata" xmlns="http://www.theronyx.com/mdasj/xmldata">


    <!-- definition of attributes -->
    <xs:attribute name="ID" type="xs:string"/>
    <xs:attribute name="ComputerTime" type="xs:string"/>
    <xs:attribute name="VarId" type="xs:string"/>
    <xs:attribute name="Value" type="xs:string"/>
    <xs:attribute name="DataType" type="xs:string"/>

    <!-- definition of complex elements -->

    <!-- DIH -->
    <xs:element name="DIH">
      <xs:complexType>
        <xs:attribute ref="ID" use="required"/>
      </xs:complexType>
    </xs:element>

    <!-- TimeStamp -->
    <xs:element name="TimeStamp">
      <xs:complexType>
        <xs:attribute ref="ComputerTime" use="required"/>
      </xs:complexType>
    </xs:element>

    <!-- Variable -->
    <xs:element name="Variable">
      <xs:complexType>
        <xs:attribute ref="VarId" use="required"/>
        <xs:attribute ref="Value" use="required"/>
        <xs:attribute ref="DataType" />
      </xs:complexType>
    </xs:element>



    <!-- Root Data Spec -->
    <xs:element name="MDASJ">
      <xs:complexType>
        <xs:sequence>
          <xs:element ref="DIH"/>
          <xs:element ref="TimeStamp"/>
          <xs:element ref="Variable"  maxOccurs="unbounded"/>
        </xs:sequence>
        <xs:attribute ref="ID" use="required"/>
      </xs:complexType>
    </xs:element>

    </xs:schema>

当前 XML 文件输出

    <?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
    <MDASJ ns1:ID="MDASJID" xsi:schemaLocation="http://www.theronyx.com/mdasj/xmldata mdasj-data.xsd" xmlns:ns1="http://www.theronyx.com/mdasj/xmldata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <ns1:DIH ns1:ID="servo1"/>
        <ns1:Variable ns1:DataType="Numeric" ns1:Value="0.19830813342577691127388561653788201510906219482421875" ns1:VarId="key1"/>
        <ns1:Variable ns1:DataType="Text" ns1:Value="-3815206174054821329" ns1:VarId="key2"/>
    </MDASJ>

期望的 XML 文件输出是

    <?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
    <MDASJ ID="MDASJID" xsi:schemaLocation="http://www.theronyx.com/mdasj/xmldata mdasj-data.xsd" xmlns="http://www.theronyx.com/mdasj/xmldata" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <DIH ID="servo1"/>
        <Variable DataType="Numeric" Value="0.19830813342577691127388561653788201510906219482421875" VarId="key1"/>
        <Variable DataType="Text" Value="-3815206174054821329" VarId="key2"/>
    </MDASJ>

最佳答案

您可以使用 NamespacePrefixMapper

marshallerDXD.setProperty("com.sun.xml.bind.namespacePrefixMapper",
                          myNsPrefixMapper);

控制 namespace 前缀:

public class MyNsPrefixMapper extends NamespacePrefixMapper
{
  public String getPreferredPrefix(String uri, String suggest, boolean require)
  {
    if("http://www.theronyx.com/mdasj/xmldata".equals(uri) ){return "";}
    return suggest;
  }

  public String[] getPreDeclaredNamespaceUris()
  {
    // String[] result = new String[1];
    // result[0] = "http://www.theronyx.com/mdasj/xmldata";
    return new String[0];
  }
}

我测试了编码:

MDASJ xml = ....;
JAXBContext context = JAXBContext.newInstance(MDASJ.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.setProperty(Marshaller.JAXB_ENCODING, "ISO-8859-1");
m.setProperty(Marshaller.JAXB_SCHEMA_LOCATION,
                     "http://www.theronyx.com/mdasj/xmldata mdasj-data.xsd");
m.setProperty("com.sun.xml.bind.namespacePrefixMapper",new MyPrefixMapper());
m.marshal(xml, System.out); 

和这个 JAXB 实现:

<dependency>
  <groupId>com.sun.xml.bind</groupId>
  <artifactId>jaxb-impl</artifactId>
  <version>2.2.2</version>
  <type>jar</type>
  <scope>compile</scope>
</dependency>

关于java - 如何使用 JAXB 编码消除元素/属性中自动生成的命名空间前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6880497/

相关文章:

java - native 方法中出现 fatal error : Using JNIEnv in non-java thread

java - 如何将 HTTP POST 请求从 Servlet 发送到外部 Web 服务?

android - 清理项目后任务 ':app:processDebugResources' 执行失败

java - 无法使用Android在mysql中插入数据

c# - 如何读取结构未知的 XML

java - 将绝对文件路径从 java 代码传递到 xslt document()

java - Jaxb - 忽略未知属性

java - 执行器完成服务 : why queue results as Future's

java - Page Rank算法计算错误的页面排名

xml - JAXB Unmarshalling - 是否可以在不使用模式验证的情况下限制元素的出现?