6.6.3 XPath Filtering

Identifier:
http://www.w3.org/TR/1999/REC-xpath-19991116

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 ensure that only specifically defined changes to the input XML document are permitted after the signature is affixed. The XPath expression can be created such that it includes all elements except those meeting specific criteria. 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 from a DigestValue calculation.

6.6.3.1 Evaluation Context Initialization

The XPath transform establishes the following evaluation context for the XPath expression given in the XPath parameter element:

6.6.3.2 Parsing Requirements for XPath Evaluation

An XML processor is used to read the input XML document and produce a parse tree capable of being used as the initial context node for the XPath evaluation, as described in the previous section. If the input is not a well-formed XML document, then the XPath transform must throw an exception.

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 XPath transform implementation uses a non-validating processor, and it encounters an external reference in the input document, then an exception must be thrown to indicate that the necessary algorithm is unavailable (The XPath transform cannot simply generate incorrect output since many applications distinguish an unverifiable signature from an invalid signature).

As a result of reading the input with an XML processor, 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, consecutive characters are grouped into a single text node.

The XPath implementation is expected to convert the information in the input XML document and the XPath expression string to the character domain prior to making any comparisons such that the result of evaluating the expression is equivalent regardless of the initial encoding of the input XML document and XPath expression.

The namespace prefix of each node appearing in the original document must be preserved by the XML processor used by the XPath transform implementation. This is necessary in order to produce the serialized result.

Although an node-set is unordered, based on the expression evaluation requirements of the XPath function library, the document order position of each node must be available, except for the attribute and namespace axes. The XPath transform imposes no order on attribute and namespace nodes during XPath expression evaluation, and expressions based on attribute or namespace node position are not interoperable. The XPath transform does define an order for namespace and attribute nodes during serialization.

6.6.3.3 XPath Transform Serialization Algorithm

A node-set is converted 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' document order positions except for attribute and namespace nodes, which do not have document order positions.

The nodes in the attribute and namespace axes will each be processed in lexicographic order, with the namespace axis preceding the attribute axis. Lexicographic comparison is performed using namespace URI as the primary key and local name as secondary key (nodes with no namespace qualification have an empty namespace URI, which is defined to be lexicographically least). Lexicographic comparison is based on the UCS codepoint values, which is equivalent to lexical ordering based on UTF-8.

The method of text generation is dependent on the node type and given in the following list:

6.6.3.4 XPath Transform Output

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 converted to UTF-8 is the output of the XPath transform. If the result is a boolean or number, then the XPath transform output is computed by converting the boolean or number to a string as if by a call to the XPath string() function, then converting to UTF-8. If the result of the XPath expression is a node-set, then the XPath transform result is computed by serializing the node-set with a UTF-8 encoding.

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. Elements within S1 are changed during signature creation (e.g. the digest value must be put inside the DigestValue and S1's SignatureValue must be subsequently calculated). To prevent these changes from invalidating the digest value in DigestValue, we add a transform that omits S1 from the digest calculation. This can be done with an XPath transform containing the following XPath expression in its XPath parameter element:

/descendant-or-self::node()[not(ancestor-or-self::dsig:Signature[@id='S1'])]

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 S1 and its descendant nodes.

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.

6.6.4 XSLT Transform

Identifier:
http://www.w3.org/TR/1999/REC-xslt-19991116

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].