7.6. x:string

(x:string object)

Converts object to a string in a way that is dependent on the type of object.

XSieve function x:string in an analogue of the XPath function string. In fact, the former is implemented through calling the latter.

There are two issue with x:string that are not obvious:

7.6.1. x:string and entities

The XPath specification doesn't define what is the string value of an entity. Even more, the data model for XPath doesn't have entities. As result, the string value of an entity is the empty string.

Example 37. Using x:string with entities

(display (x:string '(data "text1" (& nbsp) "text2")))
  ====>  text1text2

In future, I might change the semantics of the string value of an entity. For the example above, a possible result is the following.

text1 text2

I'm welcome for comments on this issue in my blog.

7.6.2. x:string and nodesets

The string value of an empty nodeset is an empty string.

If a nodeset has nodes, the nodeset is converted to a string by returning the string value of the first node in the nodeset.

To demonstrate the issue, the following sample XML data is used.

Example 38. Sample XML data

<data><b>Here</b>-is-<i><bad>#!$@</bad>some</i>-text.</data>

To get the text content of data except data in bad, the following XPath expression can be used.

Example 39. XPath for getting text content

/data//text()[not(ancestor-or-self::bad)]

Evaluating XPath gives the desired text, but the text is spread over a nodeset and x:string returns only the first chunk.

Example 40. x:string returns only the first node in a nodeset

(x:string (x:eval "/data//text()[not(ancestor-or-self::bad)]"))
        ===>  Here

To convert the nodeset to text, one can use the following Scheme code.

Example 41. Converting a nodeset to text

(apply string-append (map x:string
  (x:eval "/data//text()[not(ancestor-or-self::bad)]")))
        ===>  Here-is-some-text.

The function map applies x:string to each node in the nodeset, resulting with a lists of strings. Then the function apply calls string-append with the list of strings, resulting with the desired text.