The XPath transform output is the result of applying an
XPath expression to an input string. The XPath expression appears in a parameter
element named XPath
. The input string is equivalent to the result
of dereferencing the URI attribute of the Reference
element containing the
XPath transform, then, in sequence, applying all transforms that appear before the XPath
transform in the Reference
element's Transforms
.
The primary purpose of this transform is to omit information from the input
document that must be allowed to vary after the signature is affixed to the input
document. It is the responsibility of the XPath expression author to ensure that all
necessary information has been included in the output such that modification of the
excluded information does not affect the interpretation of the output in the
application context. One simple example of this is the omission of an
enveloped signature's SignatureValue
element.
The XPath transform establishes the following evaluation context for the
XPath expression given in the XPath
parameter element:
namespace-uri()
and local-name()
for this purpose).The XPath implementation is expected to convert all strings appearing in the XPath expression to the same encoding used by the input string prior to making any comparisons.
The XPath specification defines a node-set to be unordered. However, the specification also defines the notion of document order, and it is clear that implementations must maintain knowledge of the document order in order to correctly process the proximity position of a node. In XPath, a node's position in the document order is given by the location of the first character of the node's representative text in the document, except that an element's namespace nodes are defined to be before its attribute nodes and the relative order of namespace nodes and attribute nodes is application dependent. Within the XML-Signature application of XPath, two namespace/attribute orderings are defined:
Function: node-set parse(string Input, boolean LexOrder)
This function converts the Input string into a node-set. The function throws an exception if it cannot provide the functionality corresponding to the LexOrder setting or if the string does not contain a well-formed XML document (including byte order mark if the document has one).
Because parse() uses an XML processor to read the input, linefeeds are normalized, attribute values are normalized, CDATA sections are replaced by their content, and entity references are recursively replaced by substitution text. In addition, any consecutive characters are grouped into a single text node.
Although an XML processor reads the input XML document, validating and non-validating XML processors only behave in the same way (e.g. with respect to attribute value normalization and entity reference definition) until an external reference is encountered. If the implementation uses a non-validating processor, and it encounters an external reference in the input document, then the function should throw an exception to indicate that the necessary algorithm is unavailable (The XPath transform cannot simply generate incorrect output since many applications distinguish between an unverifiable signature versus an invalid signature).
The node-set returned by this function has a context node of the root of the input XML document, and the context position and context size are equal to 1. The function also associates a document order position P with each node. For attribute and namespace nodes, the value of P is dependent upon the LexOrder parameter. If the LexOrder is false, then P is assigned using exact order as defined in the previous section. If LexOrder is true, then the value of P for namespace and attribute nodes is assigned based on a lexicographic ordering of the namespace and attributes (as defined in the previous section). For a given element E with document order position P, N namespace nodes and A attribute nodes, the successive namespace nodes are assigned document order positions P+1 to P+N, and the successive attribute nodes are assigned document order positions P+N+1 to P+N+A.
The function associates two strings with the root node: BOM and XMLDecl. The BOM string contains the byte order mark or the empty string if there was no byte order mark. The XMLDecl strings contain the complete, unaltered input text that the XML processor absorbs while recognizing the 'XMLDecl' production rule.
The function associates a namespace-prefix string with each element, attribute and namespace node to store the namespace prefix of namespace qualified nodes. The string is empty unless the name of the node is namespace qualified.
Function: string serialize(node-set)
This function converts a node-set into a string by generating the representative text for each node in the node-set. The nodes of a node-set are processed in ascending order of the nodes' P values (document order positions) as assigned by the parse() function. The method of text generation is dependent on the node type and given in the following list:
&
,
all double quote characters with "
, and all illegal characters for the output
character encoding with hexadecimal character references (e.g. 
).&
,
all open angle brackets (<) are replaced by <
, and all illegal characters
for the output character encoding with hexadecimal character references (e.g. 
).The result of the XPath expression is a string, boolean, number, or node-set. If the result of the XPath expression is a string, then the string is the output of the XPath transform. If the result is a boolean or number, then the XPath transform output is computed by calling the XPath string() function on the boolean or number. If the result of the XPath expression is a node-set, then the XPath transform output is the string result of calling serialize() on the node-set.
For example, consider creating an enveloped signature S1 (a Signature
element
with an id
attribute equal to "S1"). The signature S1 is enveloped because its
Reference
URI indicates some ancestor element of S1. Since the DigestValue
in the Reference
is calculated before S1's SignatureValue
, the
SignatureValue
must be omitted from the DigestValue
calculation.
This can be done with an XPath transform containing the following XPath expression in its
XPath
parameter element:
serialize(parse($input, "true")/descendant-or-self::node()[
not(self::SignatureValue and parent::Signature[@id="S1"]) and
not(self::KeyInfo and parent::Signature[@id="S1"]) and
not(self::DigestValue and ancestor::*[3 and @id="S1"])]
The parse() call creates a node-set from the $input using lexicographic order for the namespace
and attribute order. The '/descendant-or-self::node()' means that all nodes in the entire parse
tree starting at the root node are candidates for the result node-set. For each node candidate,
the node is included in the resultant node-set if and only if the node test (the boolean expression
in the square brackets) evaluates to "true" for that node. The node test returns true for all
nodes except the SignatureValue
and KeyInfo
child elements and the
and the DigestValue
descendants of Signature
S1. Thus, serialize()
returns a string containing the entire $input except for omitting the parts of S1 that must change
during core processing, so these changes will not invalidate a DigestValue
computed
over the serialize() result.
Note that this expression works even if the XPath transform is implemented with a non-validating processor because S1 is identified by comparison to the value of an attribute named 'id' rather than by using the XPath id() function. Although the id() function is useful when the 'id' attribute is not named 'id', the XPath expression author will know the 'id' attribute's name when writing the expression.
It is RECOMMENDED that the XPath be constructed such that the result of this operation is a well-formed XML document. This should be the case if root element of the input resource is included by the XPath (even if a number of its descendant nodes are omitted by the XPath expression). It is also RECOMMENDED that nodes should not be omitted from the input if they affect the interpretation of the output nodes in the application context. The XPath expression author is responsible for this since the XPath expression author knows the application context.
The Transform element contains a single parameter child element
called XSLT
, whose content MUST conform to the XSL Transforms [XSLT] language syntax.
The processing rules for the XSLT transform are stated in the XSLT specification
[XSLT].