如何使用Java在特定字段上生成带有CDATA的XML?

huangapple go评论81阅读模式
英文:

How to generate with java a xml with CDATA on a specific field

问题

我想更新一段旧代码,但是我找不到使用被弃用的XmlSerializer类的正确方法,该类在Xerces 2.9.0中被弃用。建议新应用程序使用DOM Level 3 LSSerializer或JAXP的Transformation API for XML (TrAX)来序列化XML。

我需要从一个Java类生成一个XML(这没有问题),但是在XML的特定字段outerHtml上添加前缀字符<![CDATA[和后缀字符]]>

以下是我想要更新的旧代码中的"generateXmlWithCDATA"方法:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.xml.serialize.OutputFormat;
import org.apache.xml.serialize.XMLSerializer;

private static File generateXmlWithCDATA(MyObjectJava myObjectJava, File fileXmlOutput) throws JAXBException, IOException {
    JAXBContext requestJaxbContext = JAXBContext.newInstance(MyObjectJava.class);

    Marshaller marshaller = requestJaxbContext.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    // 获取一个已配置生成CDATA的Apache XMLSerializer
    try (OutputStream out = new FileOutputStream(fileXmlOutput)) {
        XMLSerializer serializer = getXMLSerializer(out);
        marshaller.marshal(myObjectJava, serializer.asContentHandler());
    }
    return fileXmlOutput;
}

private static XMLSerializer getXMLSerializer(OutputStream os) {
    // 配置OutputFormat以处理CDATA
    OutputFormat of = new OutputFormat();

    // 指定要处理为CDATA的元素。
    // 在命名空间URI和本地名称之间使用'^'似乎是xerces代码的实现细节。
    // 处理不使用命名空间的xml时,只需省略命名空间前缀,如下面的第三个CDataElement所示。
    of.setCDataElements(
            new String[] {
                "^outerHtml"   // <outerHtml>
            });

    // 设置其他任何您想要的选项
    of.setPreserveSpace(true);
    of.setIndenting(true);

    // 创建序列化器
    final XMLSerializer serializer = new XMLSerializer(of);
    serializer.setOutputByteStream(os);

    return serializer;
}

XML输出大致如下:

<MyObjectJava>
  <name>Leo</name>
  <surname>DaVinci</surname>
  <outerHtml><![CDATA[<a href="https://www.isasite.com">Is a site</a>]]></outerHtml>
</MyObjectJava>

有人可以给出一个使用新系统的示例吗?

提前感谢。

英文:

I would like to update an old piece of code, but I can't find the correct way to do it with the new system suggested from the deprecated class XmlSerializer, it was deprecated in Xerces 2.9.0. and it is recommended that new applications use the DOM Level 3 LSSerializer or JAXP's Transformation API for XML (TrAX) for serializing XML.

I need to generate an xml from a java class (no problem in that), but adding the prefix characters &lt;![CDATA[ and suffix characters ]]&gt; on the specific field outerHtml of the xml.

Here the old code with the method "generateXmlWithCDATA" i want to update:


        import java.io.File;
        import java.io.FileOutputStream;
        import java.io.IOException;
        import java.io.OutputStream;
        import java.io.Serializable;
        import java.io.StringWriter;
        import java.io.Writer;
        import java.nio.charset.StandardCharsets;
        import java.util.Date;
        import java.util.HashMap;
        import java.util.List;
        import java.util.Map;
        
        import javax.xml.bind.JAXBContext;
        import javax.xml.bind.JAXBException;
        import javax.xml.bind.Marshaller;
        
        import org.apache.commons.codec.binary.Base64;
        import org.apache.commons.io.FileUtils;
        import org.apache.commons.io.IOUtils;
        import org.apache.xml.serialize.OutputFormat;
        import org.apache.xml.serialize.XMLSerializer;

	private static File generateXmlWithCDATA(MyObjectJava myObjectJava, File fileXmlOutput) throws JAXBException, IOException {
		JAXBContext requestJaxbContext = JAXBContext.newInstance(MyObjectJava.class);
	
		Marshaller marshaller = requestJaxbContext.createMarshaller();
		marshaller.setProperty(Marshaller.JAXB_ENCODING, &quot;UTF-8&quot;);
		marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
		 // get an Apache XMLSerializer configured to generate CDATA
		try(OutputStream out = new FileOutputStream(fileXmlOutput)) {		
		    XMLSerializer serializer = getXMLSerializer(out);		
		    marshaller.marshal(myObjectJava, serializer.asContentHandler());   
		}
		return fileXmlOutput;
	}


	private static XMLSerializer getXMLSerializer(OutputStream os) {
	    // 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 &#39;^&#39; between the namespaceURI and the localname
	    // seems to be an implementation detail of the xerces code.
	    // When processing xml that doesn&#39;t use namespaces, simply omit the
	    // namespace prefix as shown in the third CDataElement below.
	    of.setCDataElements(
			    new String[] { 
			    	&quot;^outerHtml&quot;   // &lt;outerHtml&gt;
			});   
	
	    // set any other options you&#39;d like
	    of.setPreserveSpace(true);
	    of.setIndenting(true);
	
	    // create the serializer
	    final XMLSerializer serializer = new XMLSerializer(of);
	    serializer.setOutputByteStream(os);
	
	    return serializer;
	}

the xml output is something like this


        &lt;MyObjectJava&gt;
          &lt;name&gt;Leo&lt;/name&gt;
          &lt;surname&gt;DaVinci&lt;/surname&gt;
          &lt;outerHtml&gt;&lt;![CDATA[&lt;a href=&quot;https://www.isasite.com&quot;&gt;Is a site&lt;/a&gt;]]&gt;&lt;/outerHtml&gt;
        &lt;/MyObjectJava&gt;

Anyone can give a example with the new system ?

Ty in advance.

答案1

得分: 1

如果你决定使用JAXP序列化器,你可以使用序列化属性CDATA_SECTION_ELEMENTS声明要序列化为CDATA的元素,但你不能在单个元素实例的级别上控制它。

英文:

If you decide to go for the JAXP serializer, you can declare elements whose content is to be serialized as CDATA using the serialization property CDATA_SECTION_ELEMENTS, but you can't control it at the level of individual element instances.

答案2

得分: 0

感谢Michael Kay的建议,我找到了一个解决方案XD

private static File generateXmlWithCDATAV2(MyObjectJava myObjectJava, File fileXmlOutput) throws Exception {
    JAXBContext requestJaxbContext = JAXBContext.newInstance(MyObjectJava.class);
    
    Marshaller marshaller = requestJaxbContext.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    final DOMResult domResult = new DOMResult();
    marshaller.marshal(myObjectJava, domResult);
    
    Transformer transformer1 = TransformerFactory.newInstance().newTransformer();
    transformer1.setOutputProperty(OutputKeys.INDENT, "yes");
    transformer1.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
    transformer1.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, "outerHtml");
    transformer1.transform(
            new DOMSource(domResult.getNode()), 
            new StreamResult(fileXmlOutput));
    return fileXmlOutput;
}

这是一个用于生成带有CDATA的XML文件的方法。它使用了JAXBContext和Marshaller来将Java对象转换为XML,并使用Transformer将XML写入文件中。在输出的XML中,outerHtml元素将被包含在CDATA部分中。

英文:

Ty to Michael Kay suggestion, i find asolution XD

	private static File generateXmlWithCDATAV2(MyObjectJava myObjectJava, File fileXmlOutput) throws Exception {
JAXBContext requestJaxbContext = JAXBContext.newInstance(MyObjectJava.class);
Marshaller marshaller = requestJaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_ENCODING, &quot;UTF-8&quot;);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
final DOMResult domResult = new DOMResult();
marshaller.marshal(myObjectJava, domResult);
Transformer transformer1 = TransformerFactory.newInstance().newTransformer();
transformer1.setOutputProperty(OutputKeys.INDENT, &quot;yes&quot;);
transformer1.setOutputProperty(&quot;{http://xml.apache.org/xslt}indent-amount&quot;, &quot;2&quot;);
transformer1.setOutputProperty(OutputKeys.CDATA_SECTION_ELEMENTS, &quot;outerHtml&quot;);
transformer1.transform(
new DOMSource(domResult.getNode()), 
new StreamResult(fileXmlOutput));
return fileXmlOutput;
}

huangapple
  • 本文由 发表于 2023年7月27日 14:59:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76777208.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定