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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9879433/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 22:45:01  来源:igfitidea点击:

JAXB Java generating XML, Why lowercase?

javaxmljaxb

提问by user1293962

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!

谢谢!

回答by bdoughan

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 @XmlRootElementannotation 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) 的负责人,我们有一个扩展,允许您覆盖您可能感兴趣的默认名称转换算法:

回答by FAtBalloon

For specific elements...

对于特定元素...

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

For the object....

对于对象....

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

回答by Rid

My solution after put @XmlElement(name="Xxxxx") to fields and used XStream.aliasField(). This is more generic because it uses annotations and scans other class calls in the same package.

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

回答by cody.tv.weber

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. You will need a few tweaks before it can be a standalone XML.

另一个答案,如果 JAXB 不是必须的,那么您实际上可以使用 org.json jar 将对象转换为 JSONObject,然后从那里,您可以使用 XML 对象将 JSONObject 转换为 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;
}