简体   繁体   English

JAXB Java生成XML,为什么小写?

[英]JAXB Java generating XML, Why lowercase?

When I run this code: 当我运行此代码时:

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

I get 我明白了

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

Which is correct, so my question is why does it change the Employee to employee? 这是正确的,所以我的问题是为什么它将员工改为员工? Is it possible to make it print with uppercase E, instead of employee? 是否可以使用大写E而不是员工进行打印?

This is what I actually wanted to have: 这就是我真正想要的:

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

Thanks! 谢谢!

The behaviour you are seeing is the result of the standard JAXB (JSR-222) XML name to Java name conversion algorithm. 您看到的行为是标准JAXB(JSR-222) XML名称到Java名称转换算法的结果。

You can use the @XmlRootElement annotation to specify a name: 您可以使用@XmlRootElement批注指定名称:

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

I'm the EclipseLink JAXB (MOXy) lead, and we have an extension that allows you to override the default name conversion algorithm that you may be interested in: 我是EclipseLink JAXB(MOXy)的主管,我们有一个扩展,允许您覆盖您可能感兴趣的默认名称转换算法:

For specific elements... 对于特定元素......

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

For the object.... 对象....

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

My solution after put @XmlElement(name="Xxxxx") to fields and used XStream.aliasField(). 将@XmlElement(name =“Xxxxx”)放入字段并使用XStream.aliasField()后的解决方案。 This is more generic because it uses annotations and scans other class calls in the same package. 这更通用,因为它使用注释并在同一个包中扫描其他类调用。

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

An alternative answer, if JAXB is not a MUST, then you can actually use org.json jar to convert the object to a JSONObject, then from there, you can use the XML object to convert the JSONObject to an XML. 另一个答案,如果JAXB不是必须的,那么你实际上可以使用org.json jar将对象转换为JSONObject,然后从那里,你可以使用XML对象将JSONObject转换为XML。 You will need a few tweaks before it can be a standalone XML. 在它可以成为独立的XML之前,您需要进行一些调整。

A code snippet example: 代码段示例:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM