英文:
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 <![CDATA[
and suffix characters ]]>
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, "UTF-8");
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 '^' 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[] {
"^outerHtml" // <outerHtml>
});
// set any other options you'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
<MyObjectJava>
<name>Leo</name>
<surname>DaVinci</surname>
<outerHtml><![CDATA[<a href="https://www.isasite.com">Is a site</a>]]></outerHtml>
</MyObjectJava>
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, "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;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论