Java 如何在 Jaxb 准备的 XML 中添加 <![CDATA[ 和 ]]>

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24054469/
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-08-14 09:55:45  来源:igfitidea点击:

How to add <![CDATA[ and ]]> in XML prepared by Jaxb

javaxmljaxbcdata

提问by LMK

How to prepare XML with CDATA ,

如何使用 CDATA 准备 XML,

I am preraring this response via Jaxb,

我正在通过 Jaxb 准备这个回复,

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
 <SOAP-ENV:Header/>
 <soapenv:Body>
   <tem:RequestData>
     <tem:requestDocument>
        <![CDATA[
        <Request>
           <Authentication CMId="68" Function="1" Guid="5594FB83-F4D4-431F-B3C5-EA6D7A8BA795" Password="poihg321TR"/>
           <Establishment Id="4297867"/>
        </Request>
        ]]>
      </tem:requestDocument>
   </tem:RequestData>
 </soapenv:Body>
 </soapenv:Envelope>  

But from Jaxb i am not getting CDATA , how to put CDATA inside <tem:requestDocument>element.

但是从 Jaxb 我没有得到 CDATA ,如何将 CDATA 放入<tem:requestDocument>元素中。

Here is my Java Code :

这是我的 Java 代码:

  public static String test1() {
    try {
        initJB();
        String response = null;
        StringBuffer xmlStr = null;
        String strTimeStamp = null;
        com.cultagent4.travel_republic.gm.Envelope envelope = null;
        com.cultagent4.travel_republic.gm.Header header = null;
        com.cultagent4.travel_republic.gm.Body body = null;
        com.cultagent4.travel_republic.gm.RequestData requestData = null;
        com.cultagent4.travel_republic.gm.RequestDocument requestDocument = null;
        com.cultagent4.travel_republic.gm.RequestDocument.Request request = null;
        com.cultagent4.travel_republic.gm.RequestDocument.Request.Authentication authentication = null;
        com.cultagent4.travel_republic.gm.RequestDocument.Request.Establishment establishment = null;

        ObjectFactory objFact = new ObjectFactory();
        envelope = objFact.createEnvelope();
        header = objFact.createHeader();
        envelope.setHeader(header);
        body = objFact.createBody();
        requestData = objFact.createRequestData();


        requestDocument = objFact.createRequestDocument();
        request = new RequestDocument.Request();

        authentication = new RequestDocument.Request.Authentication();
        authentication.setCMId("68");
        authentication.setGuid("5594FB83-F4D4-431F-B3C5-EA6D7A8BA795");
        authentication.setPassword("poihg321TR");
        authentication.setFunction("1");
        request.setAuthentication(authentication);
        establishment = new RequestDocument.Request.Establishment();
        establishment.setId("4297867");
        request.setEstablishment(establishment);
        requestDocument.setRequest(request);
        requestData.setRequestDocument(requestDocument);
        body.setRequestData(requestData);
        envelope.setBody(body);



        jaxbMarshallerForBase = jaxbContextForBase.createMarshaller();
        OutputStream os = new ByteArrayOutputStream();


        System.out.println();
        // output pretty printed

//                jaxbMarshallerForBase.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//                jaxbMarshallerForBase.marshal(envelope, System.out);
//                jaxbMarshallerForBase.marshal(envelope, os);


        jaxbMarshallerForBase.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
        jaxbMarshallerForBase.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//            jaxbMarshallerForBase.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
// get an Apache XMLSerializer configured to generate CDATA
        XMLSerializer serializer = getXMLSerializer();


// marshal using the Apache XMLSerializer
        SAXResult result = new SAXResult(serializer.asContentHandler());

         System.out.println("*************");
        jaxbMarshallerForBase.marshal(envelope, result);
        System.out.println("--------------");



        return null;
    } catch (JAXBException ex) {
        Logger.getLogger(GM_TravelRepublic.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
        return null;
    }
}

private static XMLSerializer getXMLSerializer() {
    // configure an OutputFormat to handle CDATA
    OutputFormat of = new OutputFormat();

    // specify which of your elements you want to be handled as CDATA.
    // The use of the ; '^' between the namespaceURI and the localname
    // seems to be an implementation detail of the xerces code.
    // When processing xml that doesn't use namespaces, simply omit the
    // namespace prefix as shown in the third CDataElement below.
    of.setCDataElements(new String[]{"^Request","^Authentication","^Establishment"});


    // set any other options you'd like
   of.setPreserveSpace(true);
    of.setIndenting(true);


    StringWriter writer = new StringWriter();
    // create the serializer
    XMLSerializer serializer = new XMLSerializer(of);


    serializer.setOutputByteStream(System.out);


    return serializer;
}  

Here I am getting same xml , but without CDATA. My server is not accepting the request without CDATA.Please help.

在这里我得到相同的 xml ,但没有 CDATA 。我的服务器不接受没有 CDATA 的请求。请帮忙。

回答by albciff

I think that in your private static XMLSerializer getXMLSerializer()method you are setting wrong the CDATAelements, because your CDATAelement is <tem:requestDocument>instead of RequestAuthenticationand Establishmentwhich are the content. Try with:

我想,在你的private static XMLSerializer getXMLSerializer()方法,你要设置错误的CDATA元素,因为你的CDATA元素<tem:requestDocument>,而不是RequestAuthenticationEstablishment它们的内容。尝试:

of.setCDataElements(new String[]{"tem^requestDocument","http://tempuri.org/^requestDocument","requestDocument"});

instead of:

代替:

of.setCDataElements(new String[]{"^Request","^Authentication","^Establishment"});

Hope this helps,

希望这可以帮助,

回答by bdoughan

CDATAis character data, it looks like your server wants the part of the XML starting with Requestto come in as text. It may be enough for you to create an XmlAdapterto convert the instance of Requestto a String. The resulting characters will be escaped not in CDATA but this May fit your use case.

CDATA是字符数据,看起来您的服务器希望Request以文本开头的 XML 部分。对您来说,创建 anXmlAdapter以将 的实例转换Request为 a可能就足够了String。结果字符不会在 CDATA 中转义,但这可能适合您的用例。

Then if you really need it as CDATA in addition to the XmlAdapteryou can apply one of the strategies described in the link below:

然后,如果您真的需要它作为 CDATA 除了XmlAdapter您可以应用以下链接中描述的策略之一:

回答by Cajetan Rodrigues

From the setCDataElements method descriptionin the Apache docs :

从Apache 文档中的setCDataElements 方法描述

Sets the list of elements for which text node children should be output as CDATA.

Sets the list of elements for which text node children should be output as CDATA.

What I think that means is, the children of the tem:requestDocumentelement should all be part of one single text chunk (and not xml elements by themselves) in order for this to work. Once you've done that, probably a simple

我认为这意味着,tem:requestDocument元素的子元素都应该是一个文本块的一部分(而不是 xml 元素本身)才能使其工作。一旦你这样做了,可能是一个简单的

of.setCDataElements(new String[]{"tem^requestDocument"});

should do the trick.

应该做的伎俩。

Try it and let me know :)

试试吧,让我知道:)

回答by user2130460

Can you make the logic from this

你能从中得出逻辑吗

imports

进口

import org.dom4j.CDATA;
import org.dom4j.DocumentHelper;

sample code

示例代码

public static String appendCdata(String input) {
    CDATA cdata = DocumentHelper.createCDATA(input);      
    return cdata.asXML();
}

回答by Ashu

  1. You need to create an custom adapter class which extends the XMLAdapter class.
  1. 您需要创建一个扩展 XMLAdapter 类的自定义适配器类。

import javax.xml.bind.annotation.adapters.XmlAdapter;

导入 javax.xml.bind.annotation.adapters.XmlAdapter;

public class CDATAAdapter extends XmlAdapter {

公共类 CDATAAdapter 扩展 XmlAdapter {

@Override
public String marshal(String inStr) throws Exception {
    return "<![CDATA[" + inStr + "]]>";
}

@Override
public String unmarshal(String v) throws Exception {
    return inStr;
}

}

}

  1. Inside your Java Bean or POJO define XMLJavaTypeAdapter on the string required in CDATA

    @XmlJavaTypeAdapter(value=CDATAAdapter.class) private String message;

  2. By default, the marshaller implementation of the JAXB RI tries to escape characters. To change this behaviour we write a class that implements the CharacterEscapeHandler.

  1. 在您的 Java Bean 或 POJO 中,在 CDATA 所需的字符串上定义 XMLJavaTypeAdapter

    @XmlJavaTypeAdapter(value=CDATAAdapter.class) 私有字符串消息;

  2. 默认情况下,JAXB RI 的编组器实现会尝试转义字符。为了改变这种行为,我们编写了一个实现 CharacterEscapeHandler 的类。

This interface has an escape method that needs to be overridden.

这个接口有一个需要重写的转义方法。

import com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler;

导入 com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler;

m.setProperty("com.sun.xml.internal.bind.characterEscapeHandler",
                new CharacterEscapeHandler() {
                    @Override
                    public void escape(char[] ch, int start, int length,
                            boolean isAttVal, Writer writer)
                            throws IOException {
                        writer.write(ch, start, length);
                    }
                });

Secondly, it cn also be done via Eclipse MOXy implementation.

其次,它也可以通过 Eclipse MOXy 实现来完成。

回答by Edward Samson

Your server is expecting <tem:requestDocument>to contain text, and not a <Request>element. CDATAis really just helpful for creating hand-written XML so you don't have to worry about escaping embedded XML. The thing is, JAXBhandles escaping just fine and if your server is a good XML citizen it should treat properly escaped XML the same as XML in a CDATAblock.

您的服务器期望<tem:requestDocument>包含text,而不是<Request>元素。CDATA对创建手写 XML 真的很有帮助,因此您不必担心转义嵌入的 XML。问题是, JAXB可以很好地处理转义,如果您的服务器是一个良好的 XML 公民,它应该像CDATA块中的XML 一样正确处理转义的 XML 。

So, instead of adding a requestelement inside your requestDocumentlike you do in:

因此,不要像在requestDocument 中那样在requestDocument中添加request元素:

requestDocument = objFact.createRequestDocument();
request = new RequestDocument.Request();

...
requestDocument.setRequest(request);

You should first use JAXB to marshal requestinto a properly escaped String and set thatsa the requestDocumentvalue:

你应该先使用JAXB元帅请求到一个正确转义字符串并设置SA的requestDocument值:

requestDocument = objFact.createRequestDocument();
request = new RequestDocument.Request();

...
String escapedRequest = marshal(request);
requestDocument.setRequest(escapedRequest);

Implementing marshal(request)is left as an exercise. ;)

实施留作marshal(request)练习。;)