【问题标题】:Namespace prefix for Jaxb XmlAdapterJaxb XmlAdapter 的命名空间前缀
【发布时间】:2017-06-05 16:48:45
【问题描述】:

我正在使用 jaxb XmlAdapter 为表示属性的元素实现动态名称。我已将 xmlns 及其前缀添加到 package-info.java 中,它似乎适用于所有其他元素,但来自 XmlAdapter 的元素。我使用的是 java 1.7。以下是代码段

包信息.java


@XmlSchema(xmlns = {
            @XmlNs(namespaceURI = "http://www.kipstor.com/kif", prefix = "kif"),
            @XmlNs(namespaceURI = "http://www.kipstor.com/kpp", prefix = "kpp")},
namespace = "http://www.kipstor.com/kif",
elementFormDefault=XmlNsForm.QUALIFIED)
package com.rahal;

import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

库.java


package com.rahal;

import java.util.List;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "KIF", namespace = "http://www.kipstor.com/kif")     
public class Library {
   private String operation;
   private List<Property> properties;

   public String getOperation() {
      return operation;
   }
   @XmlElement(name = "operation", namespace =  "http://www.kipstor.com/kif")  
   public void setOperation(String operation) {
      this.operation = operation;
   }

   @XmlAnyElement
   public List<Property> getProperties() {
      return properties;
   }
   public void setProperties(List<Property> properties) {
      this.properties = properties;
   }
}

属性.java


package com.rahal;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlJavaTypeAdapter(PropertyAdapter.class)
public class Property {

   private String name;
   private String value;
   private String type;

   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public String getValue() {
      return value;
   }
   public void setValue(String value) {
      this.value = value;
   }
   public String getType() {
      return type;
   }
   public void setType(String type) {
      this.type = type;
   }

}

PropertyAdapter.java


import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class PropertyAdapter extends XmlAdapter<Element, Property>{

    @Override
    public Property unmarshal(Element element) throws Exception {
       if (null == element) {
          return null;
       }

       Property property = new Property();
       property.setName(element.getLocalName());
       property.setValue(element.getTextContent());
       return property;
    }

   @Override
   public Element marshal(Property property) throws Exception {

      Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
      Element element = document.createElementNS("http://www.kipstor.com/kif", property.getName());
      element.setTextContent(property.getValue());
      return element;
   }
}

Demo.java


package com.rahal;

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

public class Demo {
   public static void main( String[] args ) {

      try {      
          Property p1 = new Property();
          p1.setName("supGuid");
          p1.setValue(new String("2foh343fml34erre"));

          Property p2 = new Property();
          p2.setName("supId");
          p2.setValue(new String("2322333343"));

          List<Property> propList = new ArrayList<Property>();
          propList.add(p1);
          propList.add(p2);

          Library lib = new Library();
          lib.setOperation("delete");
          lib.setProperties(propList);

          JAXBContext ctx = JAXBContext.newInstance(Library.class);
          PropertyAdapter adapter = new PropertyAdapter();
          Marshaller m = ctx.createMarshaller();
          m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
          m.setAdapter(adapter);
          m.marshal(lib, System.out);

       } catch (Exception e) {
          e.printStackTrace();
       }
   }
}

输出


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<kif:KIF xmlns:kif="http://www.kipstor.com/kif" xmlns:kpp="http://www.kipstor.com/kpp">
    <kif:operation>delete</kif:operation>
    <supGuid xmlns="http://www.kipstor.com/kif">2foh343fml34erre</supGuid>
    <supId xmlns="http://www.kipstor.com/kif">2322333343</supId>
</kif:KIF>

但我希望输出如下

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<kif:KIF xmlns:kif="http://www.kipstor.com/kif" xmlns:kpp="http://www.kipstor.com/kpp">
    <kif:operation>delete</kif:operation>
    <kif:supGuid>2foh343fml34erre</supGuid>
    <kif:supId>2322333343</supId>
</kif:KIF>

【问题讨论】:

    标签: xml jaxb


    【解决方案1】:

    我能够解决这个问题,为元素设置命名空间前缀。

    PropertyAdapter.java

    @Override
      public Element marshal(Property property) throws Exception {
    
         Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
         Element element = document.createElementNS("http://www.kipstor.com/kif", property.getName());
         element.setPrefix("kif");
         element.setTextContent(property.getValue());
         return element;
      }
    

    谢谢。

    【讨论】:

      【解决方案2】:

      createElementNS 采用 qName,而不是本地名称;您应该在创建它们时使用您在 package-info 中定义的前缀来限定元素名称:

      PropertyAdapter 中替换

      Element element = document.createElementNS("http://www.kipstor.com/kif", property.getName());
      

      Element element = document.createElementNS("http://www.kipstor.com/kif", "kif:" + property.getName());
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-09-11
        • 1970-01-01
        • 1970-01-01
        • 2021-05-29
        • 1970-01-01
        • 1970-01-01
        • 2015-02-01
        相关资源
        最近更新 更多