如何迭代xs:列表?

时间:2015-05-12 22:09:59

标签: xslt

考虑架构:

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="TheList">
        <xs:simpleType>
            <xs:list itemType="xs:string" />
        </xs:simpleType>
    </xs:element>
</xs:schema>

和xml:

<TheList>
    This list has 5 values.
</TheList>

如何迭代列表中的每个单词?创建类似的东西:

<item>This</item>
<item>list</item>
<item>has</item>
<item>5</item>
<item>values.</item>

根据我找到herehere的答案,我应该做的事情如下:

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="TheList">
        <xsl:for-each select="tokenize(., ' ')">
            <item><xsl:value-of select="." /></item>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

但是,至少在Altova的XML间谍中,我收到了这个错误:

  

匹配所需序列类型的错误发生:提供的序列('5'项目)出现错误,以匹配序列类型xs:string('zero or one')

使用内置调试器,我已经能够确定在已声明为xs:list的元素上调用tokenize时抛出错误。这是有道理的,因为元素应该已经根据有关xs:list的规则进行拆分。对我来说,这表明:

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

    <xsl:template match="TheList">
        <xsl:for-each select=".">
            <item><xsl:value-of select="." /></item>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

但是,这会将列表视为单个项目,并且不会为每个单词创建新的项目元素。

for-each命令似乎将xs:list视为单个元素,而tokenize函数似乎将相同的xs:list视为多个元素。我错过了什么?

1 个答案:

答案 0 :(得分:2)

如果您正在使用模式感知转换,那么您不需要自己对值进行标记化 - 雾化过程会自动为您完成。

<xsl:template match="TheList">
    <xsl:for-each select="data(.)">
        <item><xsl:value-of select="." /></item>
    </xsl:for-each>
</xsl:template>

如果您希望代码在架构感知和非架构感知环境中工作,您可以编写

<xsl:template match="TheList">
     <xsl:for-each select="tokenize(string(.), ' ')">
        <item><xsl:value-of select="." /></item>
     </xsl:for-each>
</xsl:template>