简体   繁体   English

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

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

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.在这里,我得到相同的 xml ,但没有 CDATA。 My server is not accepting the request without CDATA.Please help.我的服务器不接受没有 CDATA 的请求。请帮忙。

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();
}
  1. You need to create an custom adapter class which extends the XMLAdapter class.您需要创建一个扩展XMLAdapter类的自定义适配器类。
import javax.xml.bind.annotation.adapters.XmlAdapter;

public class CDATAAdapter extends XmlAdapter<String, String> {

    @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在 Java Bean 或 POJO 中,在 CDATA 所需的字符串上定义XMLJavaTypeAdapter
@XmlJavaTypeAdapter(value=CDATAAdapter.class)
private String message;
  1. By default, the marshaller implementation of the JAXB RI tries to escape characters.默认情况下,JAXB RI 的编组器实现会尝试转义字符。 To change this behaviour we write a class that implements the CharacterEscapeHandler .为了改变这种行为,我们编写了一个实现CharacterEscapeHandler的类。

This interface has an escape method that needs to be overridden.这个接口有一个需要重写的转义方法。

import 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 实现来完成。

CDATA is character data, it looks like your server wants the part of the XML starting with Request to come in as text. CDATA是字符数据,看起来您的服务器希望以Request开头的 XML 部分作为文本输入。 It may be enough for you to create an XmlAdapter to convert the instance of Request to a String .创建一个XmlAdapter来将Request的实例转换为String可能就足够了。 The resulting characters will be escaped not in CDATA but this May fit your use case.结果字符不会在 CDATA 中转义,但这可能适合您的用例。

Then if you really need it as CDATA in addition to the XmlAdapter you can apply one of the strategies described in the link below:然后,如果除了XmlAdapter之外你真的需要它作为 CDATA,你可以应用下面链接中描述的策略之一:

I think that in your private static XMLSerializer getXMLSerializer() method you are setting wrong the CDATA elements, because your CDATA element is <tem:requestDocument> instead of Request Authentication and Establishment which are the content.我想,在你的private static XMLSerializer getXMLSerializer()方法,则需要设置错了CDATA元素,因为你的CDATA元素是<tem:requestDocument>代替Request AuthenticationEstablishment它们的内容。 Try with:尝试:

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

instead of:代替:

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

Hope this helps,希望这可以帮助,

From the setCDataElements method description in the Apache docs :从 Apache 文档中的setCDataElements 方法描述

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:requestDocument element should all be part of one single text chunk (and not xml elements by themselves) in order for this to work.我认为这意味着, tem:requestDocument元素的子元素都应该是一个文本块的一部分(而不是它们本身的 xml 元素)才能使其工作。 Once you've done that, probably a simple一旦你这样做了,可能是一个简单的

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

should do the trick.应该做的伎俩。

Try it and let me know :)试试吧,让我知道:)

Your server is expecting <tem:requestDocument> to contain text , and not a <Request> element.您的服务器期望<tem:requestDocument>包含text ,而不是<Request>元素。 CDATA is really just helpful for creating hand-written XML so you don't have to worry about escaping embedded XML. CDATA实际上只是有助于创建手写的 XML,因此您不必担心转义嵌入的 XML。 The thing is, JAXB handles escaping just fine and if your server is a good XML citizen it should treat properly escaped XML the same as XML in a CDATA block.问题是, JAXB可以很好地处理转义,如果您的服务器是一个良好的 XML 公民,它应该像处理CDATA块中的 XML 一样正确处理转义的 XML。

So, instead of adding a request element inside your requestDocument like you do in:因此,不要像在requestDocument 中那样在requestDocument中添加request元素:

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

...
requestDocument.setRequest(request);

You should first use JAXB to marshal request into a properly escaped String and set that sa the requestDocument value:你应该先使用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)练习。 ;) ;)

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

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