地图主要可以帮助解决两个问题:
- 流媒体,请参阅https://www.w3.org/TR/xslt-30/#maps-streaming,尽管在使用 Saxon 9.8 HE 时不能使用流媒体。
- JSON 处理,因为 JSON 对象可以分别映射到 XSLT 3 和 XPath 3.1 映射,请参阅https://www.w3.org/TR/xpath-functions/#json和https://www.w3.org/TR/xslt -30/#json
至于简单的例子,地图和数组语法和函数规范中的各个部分都有简单的例子,要使用 XSLT 中的函数,您只需确保声明函数定义的命名空间,例如
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
我不确定简单的示例能否展示一种新语言功能的强大功能,并且地图和数组具有各种功能,举个例子,通过创建地图将一些 XML 输入转换为 JSON(在一个模板中使用 XSLT xsl:map
,在另一个模板中使用 XPath map 构造函数语法)和数组并将结果序列化为json
:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
exclude-result-prefixes="xs math map array"
version="3.0">
<xsl:output method="json" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="root">
<xsl:map>
<xsl:map-entry key="local-name()">
<xsl:apply-templates/>
</xsl:map-entry>
</xsl:map>
</xsl:template>
<xsl:template match="items">
<xsl:variable name="items" as="item()*">
<xsl:apply-templates/>
</xsl:variable>
<xsl:sequence select="map { local-name() : array { $items }}"/>
</xsl:template>
<xsl:template match="item">
<xsl:sequence select="map { 'foo' : xs:integer(foo), 'bar' : string(bar) }"/>
</xsl:template>
</xsl:stylesheet>
这样就变了
<root>
<items>
<item>
<foo>1</foo>
<bar>a</bar>
</item>
<item>
<foo>2</foo>
<bar>b</bar>
</item>
</items>
</root>
到 JSON
{
"root": {
"items": [
{
"foo":1,
"bar":"a"
},
{
"foo":2,
"bar":"b"
}
]
}
}
在线http://xsltfiddle.liberty-development.net/b4GWV3。
我还在http://xsltfiddle.liberty-development.net/6qM2e27上整理了另一个示例,其中显示了一些构建地图的方法:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
exclude-result-prefixes="xs math map array"
version="3.0">
<xsl:output method="adaptive" indent="yes"/>
<!-- a map constructed with XPath 3.1 map constructor https://www.w3.org/TR/xpath-31/#id-map-constructors -->
<xsl:param name="map1" as="map(*)" select="map { 'string' : 'foo', 'number' : 3.14, 'boolean' : true(), 'sequence' : (1, 2, 3) }"/>
<xsl:param name="json-string" as="xs:string">
{
"foo" : "value 1",
"bar" : 3.14,
"baz" : true,
"items" : ["a", "b", "c" ]
}
</xsl:param>
<!-- a map constructed from a string containing JSON using the parse-json function https://www.w3.org/TR/xpath-functions/#func-parse-json -->
<xsl:param name="map2" as="map(*)" select="parse-json($json-string)"/>
<!-- a map constructed using the XSLT xsl:map and xsl:map-entry instructions https://www.w3.org/TR/xslt-30/#map-instructions -->
<xsl:param name="map3" as="map(*)">
<xsl:map>
<xsl:map-entry key="'key1'" select="'value 1'"/>
<xsl:map-entry key="'x'" select="3.1415927"/>
</xsl:map>
</xsl:param>
<!-- a map constructed by merging several maps using the map:merge function https://www.w3.org/TR/xpath-functions/#func-map-merge -->
<xsl:param name="map4" as="map(*)" select="map:merge(($map1, $map2, $map3))"/>
<!-- a map constructed by putting a new value into an existing map using the map:put function https://www.w3.org/TR/xpath-functions/#func-map-put -->
<xsl:param name="map5" as="map(*)" select="map:put($map1, 'new-key', 'new value')"/>
<xsl:template match="/">
<xsl:sequence select="$map1, $map2, $map3, $map4, $map5"/>
</xsl:template>
</xsl:stylesheet>
输出是(不幸的是,撒克逊目前没有办法使用输出方法“自适应”来漂亮地打印/缩进项目):
map{"sequence":(1,2,3),"boolean":true(),"number":3.14,"string":"foo"}
map{"items":["a","b","c"],"foo":"value 1","bar":3.14e0,"baz":true()}
map{"key1":"value 1","x":3.1415927}
map{"items":["a","b","c"],"sequence":(1,2,3),"foo":"value 1","boolean":true(),"number":3.14,"string":"foo","key1":"value 1","bar":3.14e0,"x":3.1415927,"baz":true()}
map{"sequence":(1,2,3),"boolean":true(),"number":3.14,"string":"foo","new-key":"new value"}
一个类似的例子展示了一些构造数组的基本变体是
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:map="http://www.w3.org/2005/xpath-functions/map"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
exclude-result-prefixes="xs math map array"
version="3.0">
<xsl:output method="adaptive" indent="yes"/>
<!-- array created with square array constructor https://www.w3.org/TR/xpath-31/#prod-xpath31-SquareArrayConstructor -->
<xsl:param name="array1" as="array(xs:integer)" select="[1, 2, 3, 4]"/>
<!-- array created with curly braces array constructor https://www.w3.org/TR/xpath-31/#prod-xpath31-CurlyArrayConstructor -->
<xsl:param name="array2" as="array(xs:string)" select="array{ (string-to-codepoints('A') to string-to-codepoints('E'))!codepoints-to-string(.) }"/>
<!-- if we use the square array constructor with an expression like above inside we get an array containing a sequence of strings -->
<xsl:param name="array3" as="array(xs:string*)" select="[ (string-to-codepoints('A') to string-to-codepoints('E'))!codepoints-to-string(.) ]"/>
<xsl:param name="json-array-as-string" as="xs:string">
[ { "foo" : 1 }, { "foo" : 2 }, { "foo" : 3 } ]
</xsl:param>
<!-- array constructed by parsing JSON input with function parse-json https://www.w3.org/TR/xpath-functions/#func-parse-json -->
<xsl:param name="array4" as="array(map(xs:string, xs:double))" select="parse-json($json-array-as-string)"/>
<!-- array constructed by joining two arrays using the function array:join https://www.w3.org/TR/xpath-functions/#func-array-join -->
<xsl:param name="array5" as="array(*)" select="array:join(($array1, $array2))"/>
<!-- array constructed by extracting subarray with function array:subarray https://www.w3.org/TR/xpath-functions/#func-array-subarray -->
<xsl:param name="array6" as="array(*)" select="array:subarray($array5, 3, 4)"/>
<xsl:template match="/">
<xsl:sequence select="$array1, $array2, $array3, $array4, $array5, $array6"/>
</xsl:template>
</xsl:stylesheet>
哪个输出
[1,2,3,4]
["A","B","C","D","E"]
[("A","B","C","D","E")]
[map{"foo":1.0e0},map{"foo":2.0e0},map{"foo":3.0e0}]
[1,2,3,4,"A","B","C","D","E"]
[3,4,"A","B"]
http://xsltfiddle.liberty-development.net/eiQZDbd
在发布的这个阶段,可能还值得查看 XSLT 3 中的各种测试用例以及组合的 XPath 和 XQuery 测试套件,例如: