我需要规范化以下XML的一部分:
<test xmlns="http://www.test.org/H003" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Revision="1" Version="H003">
<header authenticate="true">
<static>
<HostID>ABCDEF</HostID>
<Nonce>123456</Nonce>
<Timestamp>2017-02-20T14:41:38.965Z</Timestamp>
<PartnerID>ED123</PartnerID>
<UserID>0123</UserID>
<Product InstituteID="XX" Language="fr">XYZ</Product>
<OrderDetails>
<OrderType>ABC</OrderType>
<OrderAttribute>DDDD</OrderAttribute>
</OrderDetails>
<SecurityMedium>0000</SecurityMedium>
</static>
<mutable></mutable>
</header>
<AuthSignature>
<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></ds:CanonicalizationMethod>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"></ds:SignatureMethod>
<ds:Reference URI="#xpointer(//*[@authenticate='true'])">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"></ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></ds:DigestMethod>
<ds:DigestValue>abcdefghijklmnopqrstuvwxyz</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="X002">abcd123456</ds:SignatureValue>
</AuthSignature>
<body></body>
</test>
为此,我使用Canonicalizer和XPathAPI:
private byte[] testCanon(Document document, String xpathString) throws XXXXException {
byte[] retour;
Node node;
NodeIterator iter;
ByteArrayOutputStream output = new ByteArrayOutputStream();
try {
Canonicalizer canonicalizer = Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS);
iter = XPathAPI.selectNodeIterator(document, xpathString);
while ((node = iter.nextNode()) != null) {
copierAttributs((Element) document.getFirstChild(), (Element) node);
output.write(canonicalizer.canonicalizeSubtree(node));
}
retour = output.toByteArray();
} catch (TransformerException | InvalidCanonicalizerException | CanonicalizationException | IOException e) {
throw new XXXXException(e);
}
return retour;
}
当我用xpathString等于// ds:SignedInfo
调用selectNodeIterator时,出现错误“前缀必须成为命名空间:ds”如果名称空间xmlns:ds从SignedInfo移到父级就可以了,那么XML来自客户端,我不能要求他更改它...
谢谢