在Java中序列化文档对象,同时保留任意元素的格式
我使用下面的函数在Java中将DOM文档对象转换为字符串在Java中序列化文档对象,同时保留任意元素的格式,java,xml,serialization,Java,Xml,Serialization,我使用下面的函数在Java中将DOM文档对象转换为字符串 public static String convertDocumentToString(final Document doc) { final DOMImplementationLS domImplementation = (DOMImplementationLS) doc.getImplementation(); final LSSerializer lsSerializer = domImplementation.c
public static String convertDocumentToString(final Document doc) {
final DOMImplementationLS domImplementation = (DOMImplementationLS) doc.getImplementation();
final LSSerializer lsSerializer = domImplementation.createLSSerializer();
lsSerializer.getDomConfig().setParameter("format-pretty-print", Boolean.TRUE);
final String xml = lsSerializer.writeToString(doc);
return xml;
}
这在大多数情况下都很有效,但有些特定元素我不想格式化(例如screen DocBook元素)。所以我有两个问题:
final String exampleXml = FileUtilities.readFileContents(new File("test.xml"));
final ArrayList<String> contentsInlineElements = new ArrayList<String>();
contentsInlineElements.add("title");
contentsInlineElements.add("term");
final ArrayList<String> inlineElements = new ArrayList<String>();
inlineElements.add("prompt");
inlineElements.add("command");
inlineElements.add("firstterm");
inlineElements.add("ulink");
inlineElements.add("guilabel");
inlineElements.add("filename");
inlineElements.add("replaceable");
inlineElements.add("parameter");
inlineElements.add("literal");
inlineElements.add("classname");
inlineElements.add("sgmltag");
inlineElements.add("guibutton");
inlineElements.add("guimenuitem");
inlineElements.add("guimenu");
inlineElements.add("menuchoice");
inlineElements.add("citetitle");
final ArrayList<String> verbatimElements = new ArrayList<String>();
verbatimElements.add("screen");
verbatimElements.add("programlisting");
final Document doc = XMLUtilities.convertStringToDocument(exampleXml);
final String formattedXml = XMLUtilities.convertNodeToString(doc.getDocumentElement(), true, false, false, verbatimElements, inlineElements, contentsInlineElements, true, 1, 0);
final String exampleXml=FileUtilities.readFileContents(新文件(“test.xml”);
最终ArrayList contentsLineElements=新ArrayList();
contentsInlineElements.添加(“标题”);
内容行元素。添加(“术语”);
final ArrayList inlineElements=新的ArrayList();
inlineElements.add(“提示符”);
inlineElements.add(“命令”);
inlineElements.添加(“第一项”);
inlineElements.添加(“ulink”);
inlineElements.添加(“吉亚贝尔”);
添加(“文件名”);
inlineElements。添加(“可替换”);
inlineElements.add(“参数”);
添加(“文字”);
inlineElements.add(“classname”);
添加(“sgmltag”);
inlineElements.add(“guibutton”);
添加(“guimenuitem”);
inlineElements.add(“guimenu”);
inlineElements.添加(“菜单”);
inlineElements.添加(“citetitle”);
final ArrayList verbatimElements=新的ArrayList();
逐字逐句。添加(“屏幕”);
添加(“程序列表”);
最终文档doc=XMLUtilities.convertStringToDocument(exampleXml);
最终字符串formattedXml=XMLUtilities.convertNodeToString(doc.getDocumentElement(),true,false,false,verbatimElements,inlineElements,contentsLineElements,true,1,0);
序列化旨在通过传输介质获取数据,但不一定(甚至通常)以与输入数据的形式相同的方式获取数据,前提是该形式根据定义不包含任何额外信息(如XML文档)
如果你也需要继续设计,你必须将这些“元”信息(即格式)编码到数据本身中,例如通过转义空白等。这可能是最简单的解决方案,但这将阻止你简单地“读取”(如用眼睛)传输流,将格式化数据编码为Base64之类的格式。这将完美地在XML包装器中传输,同时保持输入编码器的原始输入数据的保真度
当然,在另一方面,您必须再次解码数据,然后才能继续进一步处理它。除了在CDATA部分之外,空白在XML文档中并不重要,并且没有任何标准工具设计用于保存它。任何相反的要求都是错误的。简单的回答是:你不能。当您告诉序列化程序进行漂亮的打印时,您正在声明使用元素间空白(即,它是可忽略的) 较长的答案是:如果不修改DOM(或它的副本),就不能这样做。IMO最简单的方法如下:
Document.adoptNode()
将该节点移动到新的DOM中。我记得这种方法有一些问题,但那是多年前的事了。如果不起作用,请使用Document.importNode()
并从源文档中显式删除该节点。我相信您可以采用节点作为文档的根,但不能保证这一点UUID.randomuid().toString()
String.replace()
将打印不漂亮的文档插入打印漂亮的文档而且,一如既往,如果您计划将这些字符串写入文件或其他面向字节的格式,则必须显式编码为UTF-8。@downvoter请解释。如果这里有错误,社区应该知道它是什么,我也应该知道。我没有投反对票,但是空白在XML文档中非常重要。唯一不重要的时候(“可忽略空白”)是当您有一个DTD专门将构造定义为“元素内容”时。看和(特别是第一个音符)好吧,现在我投了反对票。答案不正确且具有误导性,您有机会编辑/删除。在这种情况下,空白会产生重大影响,尽管它不在CDATA区域中。请参阅:“此元素显示为“逐字”;此元素中的空格和换行符非常重要。”我使用的工作流是:1。反序列化XML字符串以创建文档对象2。处理文档对象(添加和删除元素)3。将Document对象序列化回字符串,最好使用pretty print。在这种情况下,“序列化”只是一种创建内存中表示的方法,我可以通过DOM可靠地编辑XML,而不是通过传输介质移动数据。。。我不知道有任何XML库(尽管我没有仔细研究)可以从格式化中排除任意元素。我甚至不确定这是否可能