JAXB Java, генерирующий XML, Почему в нижнем регистре?

Когда я запускаю этот код:

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

public class JavaToXMLDemo {
  public static void main(String[] args) throws Exception {
    JAXBContext context = JAXBContext.newInstance(Employee.class);

    Marshaller m = context.createMarshaller();
    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

    Employee object = new Employee();
    object.setCode("CA");
    object.setName("Cath");
    object.setSalary(300);

    m.marshal(object, System.out);

  }
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
class Employee {
  private String code;

  private String name;

  private int salary;

  public String getCode() {
    return code;
  }

  public void setCode(String code) {
    this.code = code;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getSalary() {
    return salary;
  }

  public void setSalary(int population) {
    this.salary = population;
  }
}

Я получаю

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employee>
    <code>CA</code>
    <name>Cath</name>
    <salary>300</salary>
</employee>

Что правильно, поэтому мой вопрос в том, почему он меняет Employee на сотрудника? Можно ли распечатать его в верхнем регистре E вместо сотрудника?

Это то, что я действительно хотел:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employee>
    <code>CA</code>
    <name>Cath</name>
    <salary>300</salary>
</employee>

Спасибо!

Ответ 1

Поведение, которое вы видите, является результатом стандартного JAXB (JSR-222) XML-имя для Java алгоритм преобразования имен.

Вы можете использовать аннотацию @XmlRootElement для указания имени:

@XmlRootElement(name="Employee")
@XmlAccessorType(XmlAccessType.FIELD)
class Employee {
    ...
}

Я EclipseLink JAXB (MOXy), и у нас есть расширение, которое позволяет вам переопределить алгоритм преобразования имен по умолчанию, который может вас заинтересовать:

Ответ 2

Для конкретных элементов...

@XmlElement( name = "Code")
private String code;

Для объекта....

@XmlRootElement(name="Employee")
public class Employee{ ...

Ответ 3

Мое решение после размещения @XmlElement (name= "Xxxxx" ) в полях и используется XStream.aliasField(). Это более общий, поскольку он использует аннотации и сканирует вызовы других классов в одном пакете.

import java.lang.reflect.Field;
import java.util.Map;
import java.util.TreeMap;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlAttribute;
import com.thoughtworks.xstream.XStream;
import my.MyClassGeneratedFromXsdToJaxB;

public class TestChangeFirstLetterXml {

public static void main(String[] args) throws ClassNotFoundException {
    MyClassGeneratedFromXsdToJaxB myClassGeneratedFromXsdToJaxB=new MyClassGeneratedFromXsdToJaxB();
    XStream xstream = new XStream();
    xstream.autodetectAnnotations(true);
    xstream = makeAliasAnnotatedFields(xstream, MyClassGeneratedFromXsdToJaxB.class, "FirstTagOrRoot");
    //System.out.println(xstream.toXML(myClassGeneratedFromXsdToJaxB));
}

public static XStream makeAliasAnnotatedFields(XStream xstream, Class myclass, String firstTag)
        throws ClassNotFoundException {
    xstream.alias(firstTag, myclass);
    Map<String, Object[]> aliaslist = getListAlias(myclass);
    for (String key : aliaslist.keySet()) {
        Object[] aliasvalue = new Object[3];
        aliasvalue = aliaslist.get(key);
        String xmlTag = new String((String) aliasvalue[0]);
        Class<?> classJaxb = (Class<?>) aliasvalue[1];
        String tagToRename = new String((String) aliasvalue[2]);
        xstream.aliasField(xmlTag, classJaxb, tagToRename);
        System.out.println("AliasField " + xmlTag + " " + classJaxb.getName() + " " + tagToRename);

    }
    return xstream;
}

public static Map<String, Object[]> getListAlias(Class<?> classToCheck)
        throws ClassNotFoundException {
    /* Read recursive fields of the class */
    Field[] fs = classToCheck.getDeclaredFields();
    String annotationsPackage = classToCheck.getPackage().getName();
    String classSimpleName = new String(classToCheck.getSimpleName());
    /* it is necessary avoid loop */
    Map<String, Object[]> aliasStart = new TreeMap<String, Object[]>();
    /* */
    for (int i = 0; i < fs.length; i++) {
        String nameField = fs[i].getName();
        String classFieldName = new String(fs[i].getType().getName());
        String nameXmlXsd = new String("");
        String idkey = new String(annotationsPackage + ".");
        if (fs[i].isAnnotationPresent(javax.xml.bind.annotation.XmlElement.class)) {
            XmlElement atrib = fs[i].getAnnotation(XmlElement.class);
            nameXmlXsd = new String(atrib.name());
            idkey = new String(idkey + classSimpleName + ".Element." + nameField);
        } else if (fs[i].isAnnotationPresent(javax.xml.bind.annotation.XmlAttribute.class)) {
            XmlAttribute atrib = fs[i].getAnnotation(XmlAttribute.class);
            nameXmlXsd = new String(atrib.name());
            idkey = new String(idkey + classSimpleName + ".Type." + nameField);
        }

        if (aliasStart.containsKey(idkey)) /* avoid loop */
            continue;
        if (nameXmlXsd.equals("Signature")) // My particular condition
            continue;

        if (!nameXmlXsd.equals(classFieldName)) {
            // xstrem.aliasField(a,b,c)
            Object[] alias = new Object[3];
            alias[0] = new String(nameXmlXsd);
            alias[1] = classToCheck;
            alias[2] = new String(nameField);
            aliasStart.put(idkey, alias);
        }
        if (classFieldName.indexOf(annotationsPackage) > -1) {
            Class<?> c = Class.forName(classFieldName);
            Map<String, Object[]> aliaslist = getListAlias(c);
            for (String key : aliaslist.keySet()) {
                Object[] aliasvalue = new Object[3];
                aliasvalue = aliaslist.get(key);
                aliasStart.put(key, aliasvalue);
            }
        }

    }
    return aliasStart;
}
}

Ответ 4

Альтернативный ответ: если JAXB не является MUST, вы можете использовать org.json jar для преобразования объекта в JSONObject, а затем оттуда вы можете использовать объект XML для преобразования JSONObject в XML. Вам понадобится несколько настроек, прежде чем он станет автономным XML.

Пример фрагмента кода:

public static String getXMLString(Object o){
    JSONObject json = new JSONObject(o);
    String result = 
        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + 
        XML.toString(json, o.getClass().getSimpleName());
    return result;
}