如何使用Java';s文档生成器

如何使用Java';s文档生成器,java,xml,saml,Java,Xml,Saml,我有一个应用程序,它使用SAML身份验证,充当SP,因此解析SAML响应。我收到通知,与我的应用程序通信的IdP现在将开始对其SAML响应进行签名,这意味着在计算SAML签名的有效性时,注释很重要 问题就在这里——默认情况下,我用于XML解析的库会剥离这些注释节点。请参阅此示例程序: import org.apache.commons.io.IOUtils; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import jav

我有一个应用程序,它使用SAML身份验证,充当SP,因此解析SAML响应。我收到通知,与我的应用程序通信的IdP现在将开始对其SAML响应进行签名,这意味着在计算SAML签名的有效性时,注释很重要

问题就在这里——默认情况下,我用于XML解析的库会剥离这些注释节点。请参阅此示例程序:

import org.apache.commons.io.IOUtils;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

public class Main {

    public static void main(String[] args) {
        try {
            String xml = "<NameID>test@email<!---->.com</NameID>";
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            documentBuilderFactory.setNamespaceAware(true);
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            Document doc = documentBuilder.parse(IOUtils.toInputStream(xml));
            NodeList nodes = doc.getElementsByTagName("NameID");

            if (nodes == null || nodes.getLength() == 0)
            {
                throw new RuntimeException("No NameID in document");
            }

            System.out.println(nodes.item(0).getTextContent());

        } catch(Exception e) {
            System.err.println(e.getMessage());
        }
    }
}
import org.apache.commons.io.IOUtils;
导入org.w3c.dom.Document;
导入org.w3c.dom.NodeList;
导入javax.xml.parsers.DocumentBuilder;
导入javax.xml.parsers.DocumentBuilderFactory;
公共班机{
公共静态void main(字符串[]args){
试一试{
字符串xml=”test@email.com";
DocumentBuilderFactory DocumentBuilderFactory=DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder DocumentBuilder=documentBuilderFactory.newDocumentBuilder();
Document doc=documentBuilder.parse(IOUtils.toInputStream(xml));
NodeList nodes=doc.getElementsByTagName(“NameID”);
if(nodes==null | | nodes.getLength()==0)
{
抛出新的RuntimeException(“文档中没有NameID”);
}
System.out.println(nodes.item(0.getTextContent());
}捕获(例外e){
System.err.println(e.getMessage());
}
}
}
因此,该程序将打印
test@email.com
(这意味着我的SAML代码也将得到同样的结果)。这是一个问题,因为我很确定它会导致签名验证失败,而不包含注释,因为XML文档是使用
#WithComments
规范化方法签名的

有没有办法让
DocumentBuilder
/
getTextContent()
留在注释节点中,这样我的签名就不会因为缺少注释而失效


getTextContent()
的文档在这里:

您的代码实际上保留了注释

此处稍作修改:

public static void main(String[] args) throws Exception {
    String xml = "<NameID>test@email<!--foobar-->.com</NameID>";
    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
    documentBuilderFactory.setNamespaceAware(true);
    DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
    Document doc = documentBuilder.parse(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)));
    NodeList childNodes = doc.getDocumentElement().getChildNodes();
    Node[] nodes = new Node[childNodes.getLength()];
    for (int index = 0; index < childNodes.getLength(); index++) {
        nodes[index] = childNodes.item(index);
    }
    System.out.println(nodes[1].getTextContent());
}
publicstaticvoidmain(字符串[]args)引发异常{
字符串xml=”test@email.com";
DocumentBuilderFactory DocumentBuilderFactory=DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder DocumentBuilder=documentBuilderFactory.newDocumentBuilder();
Document doc=documentBuilder.parse(新的ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));
NodeList childNodes=doc.getDocumentElement().getChildNodes();
节点[]节点=新节点[childNodes.getLength()];
对于(int index=0;index
打印
foobar
。()


根元素有3个子节点,其中一个是comment节点。因此它实际上被保留了。

您的代码实际上保留了注释

此处稍作修改:

public static void main(String[] args) throws Exception {
    String xml = "<NameID>test@email<!--foobar-->.com</NameID>";
    DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
    documentBuilderFactory.setNamespaceAware(true);
    DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
    Document doc = documentBuilder.parse(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)));
    NodeList childNodes = doc.getDocumentElement().getChildNodes();
    Node[] nodes = new Node[childNodes.getLength()];
    for (int index = 0; index < childNodes.getLength(); index++) {
        nodes[index] = childNodes.item(index);
    }
    System.out.println(nodes[1].getTextContent());
}
publicstaticvoidmain(字符串[]args)引发异常{
字符串xml=”test@email.com";
DocumentBuilderFactory DocumentBuilderFactory=DocumentBuilderFactory.newInstance();
documentBuilderFactory.setNamespaceAware(true);
DocumentBuilder DocumentBuilder=documentBuilderFactory.newDocumentBuilder();
Document doc=documentBuilder.parse(新的ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));
NodeList childNodes=doc.getDocumentElement().getChildNodes();
节点[]节点=新节点[childNodes.getLength()];
对于(int index=0;index
打印
foobar
。()

根元素有3个子节点,其中一个是comment节点。所以它实际上被保留了下来