【问题标题】:XML DOM: Selecting a node with namespace by nameXML DOM:按名称选择具有命名空间的节点
【发布时间】:2015-02-20 22:33:31
【问题描述】:

我阅读了一个已签名的 XML,格式如下:

<?xml version="1.0" encoding="UTF-8"?><principal><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><ds:Reference URI="#1500-Fri Jan 30 19:11:38 BOT 2015"><ds:Transforms>s:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><ds:DigestValue>YOzKDc7CB3QvedYMF2ZBB6omlsg=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>DLZKHySIMKwFuB1wc8cR7w/UbLhYyZtul/ndFch1GCeiKrmohyNOGO82Hbcm+rFEWxK1yMx2sKtMKnuPTTCnIiZaYCLax5UJUe27AVqzpHZOc7+UKBmQoOOi3gYfAuyCZX5xBv0lrFNuigoNv6b0Z00Bu5Eu5e2zf01zceUqig40Y3yWUpEVRl+nbEUmVEBT+8fFwcigIQhqMbwFftGO8mcu55VKbGmMZS7cpwzfq+PsTrnDDHbZ9cme/8p3lWo8TGTEDTcQ2HZoSI5VAPR2/fGDGKtS5PEG0Vbb0WFdVZ+PKuOAhXqiP947xi6PP6Qv1bCbUqwsNLwTfuTjNR9lGg==</ds:SignatureValue><ds:KeyInfo><ds:KeyName>1500</ds:KeyName></ds:KeyInfo><ds:Object Id="1500-Fri Jan 30 19:11:38 BOT 2015"><SER><num>150049</num><cod>HJYafrtr3456ABDFG</cod><pais>BO</pais</SER></ds:Object></ds:Signature><Otro>Imagen</Otro></principal>

从 java 中读取:

DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
NodeList signatures = 
    doc.getElementsByTagNameNS(Constants.SignatureSpecNS ,"ds:Signature");
System.out.println("the length "+ signatures.getLength());

返回“ signatures.getLength()” = 0,我试过了:

NodeList signatures = doc.getElementsByTagNameNS(Constants.SignatureSpecNS ,"ds");
NodeList signatures = doc.getElementsByTagNameNS(Constants.SignatureSpecNS ,"Signature");

因为可以读取标签&lt;ds:Signature&gt;。如何选择这个签名节点?

【问题讨论】:

标签: java xml digital-signature


【解决方案1】:

首先,提供的 XML 输入仍然无效。我必须编辑ds:Transform 才能获得有效的文档。现在看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<principal>
  <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
    <ds:SignedInfo>
      <ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
      <ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
      <ds:Reference URI="#1500-Fri Jan 30 19:11:38 BOT 2015">
        <ds:Transforms>
          <ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
        </ds:Transforms>
        <ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
        <ds:DigestValue>YOzKDc7CB3QvedYMF2ZBB6omlsg=</ds:DigestValue>
      </ds:Reference>
    </ds:SignedInfo>
    <ds:SignatureValue>DLZKHySIMKwFuB1wc8cR7w/UbLhYyZtul/ndFch1GCeiKrmohyNOGO82Hbcm+rFEWxK1yMx2sKtMKnuPTTCnIiZaYCLax5UJUe27AVqzpHZOc7+UKBmQoOOi3gYfAuyCZX5xBv0lrFNuigoNv6b0Z00Bu5Eu5e2zf01zceUqig40Y3yWUpEVRl+nbEUmVEBT+8fFwcigIQhqMbwFftGO8mcu55VKbGmMZS7cpwzfq+PsTrnDDHbZ9cme/8p3lWo8TGTEDTcQ2HZoSI5VAPR2/fGDGKtS5PEG0Vbb0WFdVZ+PKuOAhXqiP947xi6PP6Qv1bCbUqwsNLwTfuTjNR9lGg==</ds:SignatureValue>
    <ds:KeyInfo>
      <ds:KeyName>1500</ds:KeyName>
    </ds:KeyInfo>
    <ds:Object Id="1500-Fri Jan 30 19:11:38 BOT 2015">
      <SER>
        <num>150049</num>
        <cod>HJYafrtr3456ABDFG</cod>
        <pais>BO</pais>
      </SER>
    </ds:Object>
  </ds:Signature>
  <Otro>Imagen</Otro>
</principal>

以下代码似乎可以解决您遇到的问题。

public static void Foo()
{
    try
    {
        File file = new File("YourFile.xml");

        if (file.exists() == true)
        {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbFactory.newDocumentBuilder();

            Document doc = db.parse(file);
            doc.getDocumentElement().normalize();

            NodeList signatures = doc.getElementsByTagName("ds:Signature");
            System.out.print(signatures.getLength());

            Node signatureNode = signatures.item(0);
            NodeList childNodes = signatureNode.getChildNodes();

            for (int i = 0; i < childNodes.getLength(); i++)
            {
                System.out.print(childNodes.item(i));
            }
        }
    }
    catch (Exception exception)
    {
        //  Swallow exception
    } 
}

请注意,我真正改变的是:

NodeList signatures = doc.getElementsByTagNameNS(Constants.SignatureSpecNS ,"ds:Signature");

到这里:

NodeList signatures = doc.getElementsByTagName("ds:Signature");

我希望这会有所帮助。

【讨论】:

    【解决方案2】:

    您需要指定此代码生成的解析器将提供对 XML 命名空间的支持并使用正确的 url。

    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    dbFactory.setNamespaceAware(true);
    dbFactory.setValidating(true);
    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
    Document doc = dBuilder.parse(fXmlFile);
    String docNS = "http://www.w3.org/2000/09/xmldsig#";
    Element principal = doc.getDocumentElement();
    NodeList signatures = principal.getElementsByTagNameNS(docNS ,"Signature");
    System.out.println("the length "+ signatures.getLength());
    

    希望对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-30
      • 2010-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多