提问人:4535992 提问时间:7/27/2023 更新时间:7/31/2023 访问量:46
如何使用 java 在特定字段上生成带有 CDATA 的 xml
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 的特定字段上添加前缀字符和后缀字符。<![CDATA[
]]>
outerHtml
这里是我想更新的带有方法“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);
// 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;
}
XML 输出如下所示
<MyObjectJava>
<name>Leo</name>
<surname>DaVinci</surname>
<outerHtml><![CDATA[<a href="https://www.isasite.com">Is a site</a>]]></outerHtml>
</MyObjectJava>
任何人都可以举个新系统的例子吗?
提前 Ty。
答:
1赞
Michael Kay
7/27/2023
#1
如果决定使用 JAXP 序列化程序,则可以使用 serialization 属性将其内容序列化为 CDATA 的元素,但不能在单个元素实例级别控制它。CDATA_SECTION_ELEMENTS
0赞
4535992
7/31/2023
#2
Ty 对 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;
}
评论
java.beans.XMLEncoder