Jaxb XmlAdapter的命名空间前缀

时间:2017-01-20 16:17:31

标签: xml jaxb

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

package-info.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;

Library.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;
   }
}

Property.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>

2 个答案:

答案 0 :(得分:0)

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());

答案 1 :(得分:0)

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

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;
  }

谢谢。