XSLT模板无法正确生成元素名称

时间:2016-05-16 13:07:37

标签: xml xslt sequence xslt-2.0 saxon

我有一个带有以下模板的XSLT样式表:

<xsl:template match="row/*">
    <xsl:for-each select=".">
        <saxon:assign name="count"><xsl:value-of select="$count+1" /></saxon:assign>
        <xsl:variable name="node-value" as="xs:string" select="." />
        <xsl:variable name="node-name" as="xs:string"><xsl:value-of select="preceding::fielddescription/name(*[$count])" /></xsl:variable>
        <xsl:variable name="current-node" as="xs:string"><xsl:value-of select="preceding::fielddescription/.[$count]" /></xsl:variable>
        <xsl:if test=".[not(self::F2 or self::F7)]">
            <xsl:element name="{$current-node}">
                <xsl:value-of select="normalize-space(.)" />
            </xsl:element>
        </xsl:if>
        <xsl:if test=".[self::F2]">
            <UPCs>
                <xsl:element name="{$current-node}"><xsl:value-of select="normalize-space(.)" /></xsl:element>
            </UPCs>
        </xsl:if>
        <xsl:if test=".[self::F7]">
            <xsl:element name="{$current-node}">
                <xsl:value-of select="lower-case(normalize-space(replace(., '[/ ]', '-')))" />
            </xsl:element>
        </xsl:if>
    </xsl:for-each>
</xsl:template>

我想要它做的是处理节点集中给出的每个元素,如下所示:

<fielddescription>
   <F1>ExternalId</F1>
   <F2>UPC</F2>
   <F3>Name</F3>
   <F4>Description</F4>
   <F5>ProductPageUrl</F5>
   <F6>ImageUrl</F6>
   <F7>CategoryExternalId</F7>
</fielddescription>

并为样式表找到的每个<fielddescription>生成标签名称与<row>中每个元素的值相匹配的新元素。到目前为止,我的所有样式表都适用于此模板;它不断生成带有整个序列名称的标记的节点:

<Product removed="false">
  <ExternalIdUPCNameDescriptionProductPageUrlImageUrlCategoryExternalId>ED003-QCX</ExternalIdUPCNameDescriptionProductPageUrlImageUrlCategoryExternalId>
  <UPCs>
    <ExternalIdUPCNameDescriptionProductPageUrlImageUrlCategoryExternalId>031878025147</ExternalIdUPCNameDescriptionProductPageUrlImageUrlCategoryExternalId>
  </UPCs>
  <ExternalIdUPCNameDescriptionProductPageUrlImageUrlCategoryExternalId>Sealy Naturals-Cotton Crib Mattress Pad</ExternalIdUPCNameDescriptionProductPageUrlImageUrlCategoryExternalId>
  <ExternalIdUPCNameDescriptionProductPageUrlImageUrlCategoryExternalId>Give baby plush comfort from natural cotton fibers with the innovative Sealy Naturals-Cotton Crib Mattress Pad.</ExternalIdUPCNameDescriptionProductPageUrlImageUrlCategoryExternalId>
  <ExternalIdUPCNameDescriptionProductPageUrlImageUrlCategoryExternalId>http://www.kolcraft.com/sealy-naturals-cotton-crib-mattress-pad.html</ExternalIdUPCNameDescriptionProductPageUrlImageUrlCategoryExternalId>
  <ExternalIdUPCNameDescriptionProductPageUrlImageUrlCategoryExternalId>http://www.kolcraft.com/media/catalog/product/e/d/ed003-qcx-1_1_4.jpg</ExternalIdUPCNameDescriptionProductPageUrlImageUrlCategoryExternalId>
  <ExternalIdUPCNameDescriptionProductPageUrlImageUrlCategoryExternalId>bedding-pads</ExternalIdUPCNameDescriptionProductPageUrlImageUrlCategoryExternalId>
  <Attributes>
    <Attribute id="BV_FE_FAMILY">
      <Value>ED003</Value>
    </Attribute>
    <Attribute id="BV_FE_EXPAND">
      <Value>BV_FE_FAMILY:ED003</Value>
    </Attribute>
  </Attributes>
</Product>

我的模板出错了什么?我还应该注意到我使用了<saxon:assign>功能,因为我不知道如何让样式表与更新的变量一起工作......我知道有一个更好的方法来做这个用递归,但我无法想办法让它发挥作用。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

只需使用

<xsl:template match="row/F2">
  <xsl:variable name="pos" as="xs:integer"><xsl:number count="*"/></xsl:variable>
  <xsl:variable name="node-name" as="xs:string" select="name(preceding::fielddescription/*[$pos])"/>
            <UPCs>
                <xsl:element name="{$node-name}"><xsl:value-of select="normalize-space(.)" /></xsl:element>
            </UPCs>
</xsl:template>

<xsl:template match="row/F7">
  <xsl:variable name="pos" as="xs:integer"><xsl:number count="*"/></xsl:variable>
  <xsl:variable name="node-name" as="xs:string" select="name(preceding::fielddescription/*[$pos])"/>
            <xsl:element name="{$node-name}">
                <xsl:value-of select="lower-case(normalize-space(replace(., '[/ ]', '-')))" />
            </xsl:element>
</xsl:template>

<xsl:template match="row/*[not(self::F2 or self::F7)]">
  <xsl:variable name="pos" as="xs:integer"><xsl:number count="*"/></xsl:variable>
  <xsl:variable name="node-name" as="xs:string" select="name(preceding::fielddescription/*[$pos])"/>

            <xsl:element name="{$node-name}">
                <xsl:value-of select="normalize-space(.)" />
            </xsl:element>


</xsl:template>

根据您在祖先元素模板中使用apply-templates的位置和方式,您可以将<xsl:variable name="pos" as="xs:integer"><xsl:number count="*"/></xsl:variable>替换为<xsl:variable name="pos" select="position()"/>。但我们需要看到其余的代码。