使用javax解析器将元素添加到XML而无需修改文档

时间:2015-04-08 15:49:51

标签: java xml parsing

我正在尝试向xml文档添加元素。元素是成功添加的,但问题是,解析器在其他地方修改原始xml文件,例如它交换命名空间和id属性或删除重复的命名空间定义。我需要添加特定元素才能获得完全相同的文档(相同的语法,保留的空格)。我非常感谢任何建议。这是我的代码:

public void appendTimestamp(String timestamp, String signedXMLFile, String timestampedXMLFile){
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

    try{
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new File(signedXMLFile));

        XPath xPath = XPathFactory.newInstance().newXPath();
        NodeList list = (NodeList)xPath.evaluate("//*[local-name()='Signature']/*[local-name()='Object']/*[local-name()='QualifyingProperties']", doc, XPathConstants.NODESET);

        if(list.getLength() != 1){
            throw new Exception();
        }

        Node node = list.item(0);
        Node unsignedProps = doc.createElement("xades:UnsignedProperties");
        Node unsignedSignatureProps = doc.createElement("xzep:UnsignedSignatureProperties");
        Node timestampNode = doc.createElement("xzep:SignatureTimeStamp");
        timestampNode.appendChild(doc.createTextNode(timestamp));

        unsignedSignatureProps.appendChild(timestampNode);
        unsignedProps.appendChild(unsignedSignatureProps);
        node.appendChild(unsignedProps);

        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "no");
        transformer.setOutputProperty(OutputKeys.METHOD, "xml");
        transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

        DOMSource source = new DOMSource(doc);

        StringWriter writer = new StringWriter();
        StreamResult stringWriter = new StreamResult(writer);
        transformer.transform(source, stringWriter);

        writer.flush();
        System.out.println(writer.toString());

    }catch(Exception e){
        e.printStackTrace();
    }
}

原始xml文件:

...    
<ds:Object Id="objectIdVerificationObject" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
...

修改后的xml文件:

...
<ds:Object xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="objectIdVerificationObject">
...

1 个答案:

答案 0 :(得分:0)

如果使用dom模型,则读取整个xml文件,然后在内存中将其表示为节点树,然后以编写器确定的方式保存到xml。因此,几乎不可能保留原始的xml格式,因为您无法控制它,例如节点树中根本没有表示空格。

您需要部分阅读原始xml并将其内容ouptut保存到新文件中,保留所读取的内容,然后在&#34;右边&#34;你需要添加你的新内容,然后继续简单的原始内容。

例如,您可以使用XMLStreamWriterXMLStreamReader来实现这一目标,因为它们可以提供&#34;低...&#34;等级操作。

但是可能更容易将xml作为文本行一次复制直到您识别插入点,然后创建新的xml部分并将其作为文本附加并继续复制。