I discovered several flaws in the string-range() XPointer function implementation. See http://www.w3.org/TR/xptr-xpointer/#stringrange for the specification. 1. Some edge cases fail: $ ./test-xpointer '<a>xyzw</a>' "string-range(/a, 'xy', 1, 4)" -:2: element include: XInclude error : XPointer evaluation failed: #xpointer(string-range(/a, 'xy', 1, 4)) -:2: element include: XInclude error : could not load /tmp/tmp.XXXXWeW45c, and no fallback was found <?xml version="1.0"?> <root><include xmlns="http://www.w3.org/2003/XInclude" href="/tmp/tmp.XXXXWeW45c" xpointer="xpointer(string-range(/a, 'xy', 1, 4))"/></root> $ ./test-xpointer '<a>xyzw</a>' "string-range(/a, 'xy', 1, 3)" -:2: element include: XInclude error : XPointer evaluation failed: #xpointer(string-range(/a, 'xy', 1, 3)) -:2: element include: XInclude error : could not load /tmp/tmp.XXXXdTlLwI, and no fallback was found <?xml version="1.0"?> <root><include xmlns="http://www.w3.org/2003/XInclude" href="/tmp/tmp.XXXXdTlLwI" xpointer="xpointer(string-range(/a, 'xy', 1, 3))"/></root> 2. Returned strings are typically one character longer than requested: $ ./test-xpointer '<a>xyzw</a>' "string-range(/a, 'xy', 1, 2)" <?xml version="1.0"?> <root>xyz</root> 3. Searching for a single-character string triggers an infinite loop: $ ./test-xpointer '<a>xyzw</a>' "string-range(/a, 'x')" 4. Character counting is broken for non-ASCII characters: $ ./test-xpointer '<a>żółw</a>' "string-range(/a, 'żółw', 1, 4)" <?xml version="1.0"?> <root>żó</root>