如何忽略JaxB中元素名称的大小写
如标题中所述,我想忽略文档中元素名称的大小写。
static class XY433 {    @XmlAttribute(name = "C200")
    String c200;
    @XmlAttribute(name = "C215")
    String c215;
    @XmlAttribute(name="F001")
    String f001;
    @XmlAttribute(name="f001")
    String lcf001; // I want to avoid this duplication
}
我尝试使用Blaise Doughan发布的代码:
private static class ToLowerCaseNamesStreamReaderDelegate extends StreamReaderDelegate {    public ToLowerCaseNamesStreamReaderDelegate(XMLStreamReader xsr) {
        super(xsr);
    }
    @Override
    public String getAttributeLocalName(int index) {
        return super.getAttributeLocalName(index).toLowerCase();
    }
    @Override
    public String getLocalName() {
        return super.getLocalName().toLowerCase();
    }
}
@XmlRootElement(name="doc")
static class Doc {
    @XmlElement(name="element")
    List<Element> elements;
}
static class Element {
    @XmlAttribute(name = "abc")
    String abc;
}
public static void main(String[] args) throws Exception {
    XMLInputFactory xif = XMLInputFactory.newInstance();
    XMLStreamReader xsr = xif.createXMLStreamReader(new FileInputStream("LowerCaseElementNamesFilterTest.xml"));
    Unmarshaller u = JAXBContext.newInstance(Doc.class).createUnmarshaller();
    //Do unmarshalling
    Doc doc = (Doc) u.unmarshal(new ToLowerCaseNamesStreamReaderDelegate(xsr));
    System.out.println(doc.elements.get(0).abc);
    System.out.println(doc.elements.get(1).abc);
    System.out.println(doc.elements.get(2).abc);
}
这实际上是行不通的。
null2
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
    at java.util.ArrayList.RangeCheck(ArrayList.java:546)
    at java.util.ArrayList.get(ArrayList.java:321)
    at com.hre.commons.tec.xml.LowerCaseElementNamesFilter.main(LowerCaseElementNamesFilter.java:58)
对于此XML:
<doc>    <Element ABC="1"></Element>
    <element Abc="1"></element>
    <element abc="2"></element>
</doc>
回答:
您可以将所有属性映射到小写的节点名称,然后包装XMLStreamReader以对其返回的所有属性/元素名称调用toLowerCase()。然后从该XMLStreamReader解组。
我最近为此问题添加了对EclipseLink JAXB(MOXy)的增强请求,请随时提供其他信息:
- https://bugs.eclipse.org/bugs/show_bug.cgi?id=331241
 
import javax.xml.bind.annotation.XmlAttribute;import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Customer {
    private int id;
    private String name;
    private Address address;
    @XmlAttribute
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
}
public class Address {
    private String street;
    public String getStreet() {
        return street;
    }
    public void setStreet(String street) {
        this.street = street;
    }
}
import java.io.FileInputStream;import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.StreamReaderDelegate;
public class Demo {
    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Customer.class);
        XMLInputFactory xif = XMLInputFactory.newInstance();
        XMLStreamReader xsr = xif.createXMLStreamReader(new FileInputStream("input.xml"));
        xsr = new MyStreamReaderDelegate(xsr);
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Customer customer = (Customer) unmarshaller.unmarshal(xsr);
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(customer, System.out);
    }
    private static class MyStreamReaderDelegate extends StreamReaderDelegate {
        public MyStreamReaderDelegate(XMLStreamReader xsr) {
            super(xsr);
        }
        @Override
        public String getAttributeLocalName(int index) {
            return super.getAttributeLocalName(index).toLowerCase();
        }
        @Override
        public String getLocalName() {
            return super.getLocalName().toLowerCase();
        }
    }
}
将阅读以下XML文档:
<CUSTOMER ID="1">    <NAME>Jane Doe</NAME>
    <ADDRESS>
        <STREET>123 A Street</STREET>
    </ADDRESS>
</CUSTOMER>
<CuSToMeR Id="1">
    <NaMe>Jane Doe</NAME>
    <AdDrEsS>
        <STREET>123 A Street</STREET>
    </AdDRrEsS>
</CuSToMeR>
并编写以下XML:
<customer id="1">   <address>
      <street>123 A Street</street>
   </address>
   <name>Jane Doe</name>
</customer>
以下是更详细示例的链接:
- http://bdoughan.blogspot.com/2010/12/case-insensitive-unmarshalling.html
 
您的代码可在我的环境中运行(包含随附的JAXB和EclipseLink JAXB(MOXy)2.2的JDK
1.6.0_20,我也在使用StAX的默认实现)。当我运行您的示例时:
import java.io.FileInputStream;import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.StreamReaderDelegate;
public class Example {
    private static class ToLowerCaseNamesStreamReaderDelegate extends StreamReaderDelegate {
        public ToLowerCaseNamesStreamReaderDelegate(XMLStreamReader xsr) {
            super(xsr);
        }
        @Override
        public String getAttributeLocalName(int index) {
            return super.getAttributeLocalName(index).toLowerCase();
        }
        @Override
        public String getLocalName() {
            return super.getLocalName().toLowerCase();
        }
    }
    @XmlRootElement(name="doc")
    static class Doc {
        @XmlElement(name="element")
        List<Element> elements;
    }
    static class Element {
        @XmlAttribute(name = "abc")
        String abc;
    }
    public static void main(String[] args) throws Exception {
        XMLInputFactory xif = XMLInputFactory.newInstance();
        XMLStreamReader xsr = xif.createXMLStreamReader(new FileInputStream("LowerCaseElementNamesFilterTest.xml"));
        Unmarshaller u = JAXBContext.newInstance(Doc.class).createUnmarshaller();
        //Do unmarshalling
        Doc doc = (Doc) u.unmarshal(new ToLowerCaseNamesStreamReaderDelegate(xsr));
        System.out.println(doc.elements.get(0).abc);
        System.out.println(doc.elements.get(1).abc);
        System.out.println(doc.elements.get(2).abc);
    }
}
我得到以下输出:
11
2
讲话:
线程“ main”中的异常javax.xml.bind.UnmarshalException-
带有链接的异常:[javax.xml.bind.UnmarshalException:需要插入解组器的名称空间URI和本地名称。]位于com.sun.xml.bind。
v2.runtime.unmarshaller.UnmarshallerImpl.handleStreamException(UnmarshallerImpl.java:425)位于com.sun.xml.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:362)位于com.sun.xml.bind
v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:332)
您是否尝试过修改委托?
@Overridepublic String getAttributeLocalName(int index) {
    return super.getAttributeLocalName(index).toLowerCase().intern();
}
@Override
public String getLocalName() {
    return super.getLocalName().toLowerCase().intern();
}
以上是 如何忽略JaxB中元素名称的大小写 的全部内容, 来源链接: utcz.com/qa/410501.html

