3

我想将一个 java 对象编组为 xml 字符串。因此,我得到了一个模式,我从中生成 JAXB 类。有一个 set 方法(对应于模式中十六进制类型的元素),我必须在其中设置一个字符串。字符串大小约为 2566。通过 setter 方法将数据设置到对象中后,我调用 marshaller 传递 stringWriter 参数。

但是在打印 stringWriter 时,我看到它被截断了。我没有看到整个 2566 个字符。

怎么了?有任何想法吗?

谢谢!

更新:

我想我找到了问题所在。我必须找到一个合适的标题,因为我对问题的推理是错误的!!问题如下:我的架构中有一个“hexbinary”元素。生成的类有相应的 set/get 方法。要设置值,我使用了 apache commons 包的 HexEncodeString 方法,并意识到编组器在十六进制标记中显示 36383639 字符串“hi”,其实际十六进制编码为 6869 :( 因此,问题是编组后的 xml 有一个标记# of chars 的值大于原始字符,并且不会像我之前想的那样被截断!

感谢Blaise Doughan的代码。我已经修改它并重现了这个问题。

首先是一个示例模式:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">

  <xs:complexType name="Root">
    <xs:sequence>
      <xs:element name="string" type="xs:string" minOccurs="0"/>
            <xs:element name="a" type="xs:hexBinary" minOccurs="0"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>

有了这个,我生成了 ObjectFactory 类和 Root 类。我必须修改 ObjectFactory 类以包含 JAXBElement,以便我可以将它传递给 Marshaller。有了这些,我参加了 Blaise Doughan 的 Demo 课程并将其修改为:

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);      

    // The object factory
    ObjectFactory objFactory = new ObjectFactory();
    Root root = new Root();
    String str = new String("hi");
    String val = Hex.encodeHexString(str.getBytes());
    root.setString(str);
    root.setArr(val.getBytes());

        System.out.println("val="+val);
        System.out.println("getString ="+root.getString());
        System.out.println("getArr="+new String(root.getArr()));

        // Marshal the object to a StringWriter
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
        marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.example.com/schema.xsd");
        StringWriter stringWriter = new StringWriter();
        marshaller.marshal(objFactory.createRoot(root),stringWriter);
//      marshaller.marshal(root, stringWriter);

        // Convert StringWriter to String
        String xml = stringWriter.toString();
        System.out.println(xml);

        // Unmarshal the XML and check length of long String
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Root unmarshalledRoot = (Root) unmarshaller.unmarshal(new StringReader(xml));
        System.out.println(root.getString().length());
        System.out.println(root.getString());
        System.out.println(new String(root.getArr()).length());
        System.out.println(new String(root.getArr()));
    }

}

我得到的输出是:

val=6869
getString =hi
getArr=6869
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns3:Root xsi:schemaLocation="http://www.example.com/schema.xsd" xmlns:ns3="http://example.com/root" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <string>hi</string>
    <arr>36383639</arr>
</ns3:Root>

Exception in thread "main" javax.xml.bind.UnmarshalException: unexpected element (uri:"http://example.com/root", local:"Root"). Expected elements are (none)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:631)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:236)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:231)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportUnexpectedChildElement(Loader.java:105)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext$DefaultRootLoader.childElement(UnmarshallingContext.java:1038)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:467)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:448)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:137)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:501)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:400)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl$NSContentDriver.scanRootElementHook(XMLNSDocumentScannerImpl.java:626)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:3103)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:922)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
    at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:200)
    at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:173)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:137)
    at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:194)
    at example.Demo.main(Demo.java:43)

为什么 arr 标签是 36383639 而不是 6869?

4

1 回答 1

1

NEW ANSWER

In your sample code val is the hexBinary representation of str.getBytes(). But the value you are setting on the arr property is the bytes from the hex encoded String.

String str = new String("hi");
String val = Hex.encodeHexString(str.getBytes());
root.setString(str);
root.setArr(val.getBytes());

I believe what you mean to do is the following:

String str = new String("hi");
String val = Hex.encodeHexString(str.getBytes());
root.setString(str);
root.setArr(str.getBytes());

Which will produce the following output

val=6869
getString =hi
getArr=hi
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root xsi:schemaLocation="http://www.example.com/schema.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <string>hi</string>
    <a>6869</a>
</root>

Put another way

    String str = new String("hi");
    System.out.print("String:  " + str);
    System.out.println(" hexBinary:  " + Hex.encodeHexString(str.getBytes()));
    String val = Hex.encodeHexString(str.getBytes());
    System.out.print("String:  " + val);
    System.out.println(" hexBinary:  " + Hex.encodeHexString(val.getBytes()));

Will output:

String:  hi hexBinary:  6869
String:  6869 hexBinary:  36383639

ORIGINAL ANSWER

I have not been able to reproduce the issue that you are seeing. I am using a String size of 500000. Below is what I have tried (does this sample work for you?). Is it possible that the truncation is due to the console you are writing the long String to?

Demo

package forum12146217;

import java.io.*;
import javax.xml.bind.*;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(Root.class);

        // Build a long String
        StringBuilder stringBuilder = new StringBuilder();
        for(int x=0; x<500000; x++) {
            stringBuilder.append("a");
        }
        Root root = new Root();
        root.setString(stringBuilder.toString());
        System.out.println(root.getString().length());

        // Marshal the object to a StringWriter
        Marshaller marshaller = jc.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
        marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.example.com/schema.xsd");
        StringWriter stringWriter = new StringWriter();
        marshaller.marshal(root, stringWriter);

        // Convert StringWriter to String
        String xml = stringWriter.toString();
        //System.out.println(xml);

        // Unmarshal the XML and check length of long String
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Root unmarshalledRoot = (Root) unmarshaller.unmarshal(new StringReader(xml));
        System.out.println(unmarshalledRoot.getString().length());
    }

}

Root

package forum12146217;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Root {

    private String string;

    public String getString() {
        return string;
    }

    public void setString(String string) {
        this.string = string;
    }

}

Output

500000
500000
于 2012-08-27T17:31:14.680 回答