XSLT - 如何判断具有特定属性值的元素是否是匹配系列中的最后一个

XSLT - How to tell if an element with specific attribute value is the last in the matching series

我有以下 XSLT 模板

<xsl:template match="xsd:element[@name != '' and not(starts-with(@type, 'common:'))]">
    <xsl:if test="position() != last()">
        "<xsl:value-of select="@name"/>", 
    </xsl:if>
    <xsl:if test="position() = last()">
        "<xsl:value-of select="@name"/>"
    </xsl:if>
</xsl:template>

尝试匹配所有名称非空且类型不以 'common:' 开头的元素,然后它将生成这些元素名称的逗号分隔列表。

所以如果应用于

<xsd:element name="One"     type="String"/>
<xsd:element name=""        type="String"/>
<xsd:OtherNode />
<xsd:element name="Two"     type="common:Characters"/>
<xsd:element name="Three"   type="Long"/>
<xsd:OtherNode />

它应该生成

"One",
"Three"

注意"Three"

后面没有逗号

但听起来 position() 和 last() 有问题,因为在打印其值时听起来不正确,并且总是有一个逗号 ','

"One",
"Three",

将由 XSLT 处理的输入 XML 的完整样本是 XSD 类似于

<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns:xsd="[h t t p] ://www.w3.org/2001/XMLSchema"
           xmlns:common="[http]://abc.com/common/1.0">

    <!-- definition of simple elements -->
    <xsd:element name="orderperson" type="xsd:string"/>
    <xsd:element name="name"        type="xsd:string"/>
    <xsd:element name="address"     type="xsd:string"/>
    <xsd:element name="city"        type="xsd:string"/>
    <xsd:element name="country"     type="xsd:string"/>
    <xsd:element name="title"       type="xsd:string"/>
    <xsd:element name="note"        type="xsd:string"/>
    <xsd:element name="quantity"    type="xsd:positiveInteger"/>
    <xsd:element name="price"       type="common:decimal"/>

    <!-- definition of complex elements -->
      <xsd:complexType name="shipto">
        <xsd:sequence>
          <xsd:element ref="name"/>
          <xsd:element ref="address"/>
          <xsd:element ref="city"/>
          <xsd:element ref="country"/>
        </xsd:sequence>
      </xsd:complexType>

      <xsd:complexType name="item">
        <xsd:sequence>
          <xsd:element ref="title"/>
          <xsd:element ref="note" minOccurs="0"/>
          <xsd:element ref="quantity"/>
          <xsd:element ref="price"/>
        </xsd:sequence>
      </xsd:complexType>

      <xsd:complexType name="shiporder">
        <xsd:sequence>
          <xsd:element ref="orderperson"/>
          <xsd:element ref="shipto"/>
          <xsd:element ref="item" maxOccurs="unbounded"/>
        </xsd:sequence>
      </xsd:complexType>

</xsd:schema> 

以下是我的 XSLT 的一部分,删除了不相关的部分以保持简短

<xsl:stylesheet version="2.0" 
            xmlns:xsl="[http]://www.w3.org/1999/XSL/Transform"
            xmlns:xsd="[http]://www.w3.org/2001/XMLSchema"
            xmlns:xml="[http]://www.w3.org/XML/1998/namespace"
            xmlns:common="[http]://abc.com/common/1.0">
<xsl:output method="text" media-type="text/xml" indent="yes" encoding="ISO-8859-1" />

    <xsl:template match="/">
        <xsl:call-template name="pre-properties"/>
         <xsl:apply-templates/>
         <xsl:call-template name="post-properties"/>
    </xsl:template>

    <xsl:template match="/xsd:schema/xsd:complexType/xsd:sequence/xsd:element"/>

<xsl:template name="pre-properties">
    {
<xsl:template name="post-properties">
    }
</xsl:template>

<xsl:template match="xsd:element[@name != '' and not(starts-with(@type, 'common:'))]">
        <xsl:if test="position() != last()">
            "<xsl:value-of select="@name"/>", 
        </xsl:if>
        <xsl:if test="position() = last()">
            "<xsl:value-of select="@name"/>"
        </xsl:if>
</xsl:template>
</xsl:stylesheet>

将检查移动到谓词中,例如

<xsl:template match="xsd:element[@name != '' and not(starts-with(@type, 'common:'))][position() != last()]">
"<xsl:value-of select="@name"/>", 
</xsl:template>

<xsl:template match="xsd:element[@name != '' and not(starts-with(@type, 'common:'))][position() = last()]">
"<xsl:value-of select="@name"/>"
</xsl:template>

或者您可以尝试

<xsl:value-of select="//xsd:element[@name != '' and not(starts-with(@type, 'common:'))]/concat('&quot;', @name, '&quot;')" separator=", "/>

您想输出这些值的位置。