Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中序列化文档对象,同时保留任意元素的格式_Java_Xml_Serialization - Fatal编程技术网

在Java中序列化文档对象,同时保留任意元素的格式

在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

我使用下面的函数在Java中将DOM文档对象转换为字符串

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元素)。所以我有两个问题:

  • 在像上面的代码那样用Java格式化XML时,有没有办法跳过某些元素
  • 如果没有,是否有其他方法可以将文档转换为字符串,同时保留任意元素的布局 请注意,我过去也使用过Transformer(请参阅),但它没有保留CDATA部分

    更新:

    我很清楚,我正在对XML进行反序列化和序列化,以便创建一个可以通过DOM编程编辑的文档对象,序列化过程最好是“漂亮地打印”生成的XML(某些任意元素除外)

    更新2:

    最后,我创建了一个自定义函数,用于将节点转换为具有可选格式的字符串。请参见调用的convertNodeToString函数,如下所示:

    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最简单的方法如下:

  • 标识要保留的节点。我假设您有一个ID,或者使用XPath以其他方式选择它
  • 调用
    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库(尽管我没有仔细研究)可以从格式化中排除任意元素。我甚至不确定这是否可能