xslt - 如何增加 xslt 中每个节点集的值

标签 xslt

我有这个 xml:

<root>
    <row>
        <number>1001461</number>
        <unit>CAN</unit>
    </row>
    <row>
        <number>1001462</number>
        <unit>KG</unit>
    </row>
</root>

我的 Xslt:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="xml" indent="yes"/>
    <xsl:param name="formid" select="60202" />


  <xsl:template match="@* | node()">
      <DocumentElement>
          <xsl:apply-templates>
            <xsl:with-param name="primarykey" select="position()"/>
          </xsl:apply-templates>
      </DocumentElement>
    </xsl:template>

  <xsl:template match="row" name="trow">
    <xsl:param name="primarykey"/>
    <xsl:for-each select="*">
      <SaveDataTable>
        <KeyName>
          <xsl:value-of select="name()"/>
        </KeyName>
        <KeyValue>
          <xsl:value-of select="."/>
        </KeyValue>
        <PrimaryKey>
          <xsl:value-of select="concat('-',$primarykey)"/>
        </PrimaryKey>
        <FormId>
          <xsl:value-of select="$formid"/>
        </FormId>
      </SaveDataTable>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

预期输出:(请注意,前两个 <PrimaryKey> 为 -1,后两个为 -2,这就是我需要的)

<DocumentElement>
    <SaveDataTable>
        <KeyName>number</KeyName>
        <KeyValue>1001461</KeyValue>
        <PrimaryKey>-1</PrimaryKey>
        <FormId>60202</FormId>
    </SaveDataTable>
    <SaveDataTable>
        <KeyName>unit</KeyName>
        <KeyValue>CAN</KeyValue>
        <PrimaryKey>-1</PrimaryKey>
        <FormId>60202</FormId>
    </SaveDataTable>
    <SaveDataTable>
        <KeyName>number</KeyName>
        <KeyValue>1001462</KeyValue>
        <PrimaryKey>-2</PrimaryKey>
        <FormId>60202</FormId>
    </SaveDataTable>
    <SaveDataTable>
        <KeyName>unit</KeyName>
        <KeyValue>KG</KeyValue>
        <PrimaryKey>-2</PrimaryKey>
        <FormId>60202</FormId>
    </SaveDataTable>
</DocumentElement>

基本上对于每个 <row>...</row> <PrimaryKey>-1</PrimaryKey>应该减 1,但它没有发生。所有<PrimaryKey>元素的值为 -1,而不是 -1、-2 等。

==============================================

更新: 我有点让它工作,但我不确定它是否有效。

工作 xslt(可能需要改进):

<xsl:stylesheet version="1.0" exclude-result-prefixes="msxsl" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
    <xsl:output method="xml" indent="yes"/>
    <xsl:param name="formid" select="60202"/>
    <xsl:template match="@* | node()">
        <DocumentElement>
            <xsl:for-each select="row">
                <xsl:call-template name="trow">
                    <xsl:with-param name="primarykey" select="position()"/>
                </xsl:call-template>
            </xsl:for-each>
        </DocumentElement>
    </xsl:template>
    <xsl:template name="trow">
        <xsl:param name="primarykey"/>
        <xsl:for-each select="*">
            <SaveDataTable>
                <KeyName>
                    <xsl:value-of select="name()"/>
                </KeyName>
                <KeyValue>
                    <xsl:value-of select="."/>
                </KeyValue>
                <PrimaryKey>
                    <xsl:value-of select="concat('-',$primarykey)"/>
                </PrimaryKey>
                <FormId>
                    <xsl:value-of select="$formid"/>
                </FormId>
            </SaveDataTable>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

最佳答案

另一种方法(采用“推”而不是“拉”风格)会将处理分解为模板:

<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

    <xsl:output method="xml" indent="yes"/>
    <xsl:param name="formid" select="60202"/>

将整个文档的结果包装在 DocumentElement 中。

    <xsl:template match="/">
        <DocumentElement>
          <xsl:apply-templates/>
        </DocumentElement>
    </xsl:template>

对于每一行,获取其位置编号。我们使用 xsl:number 而不是 position() 因为我们不想计算文本节点。

    <xsl:template match="row" priority="10">
      <xsl:variable name="pos">
        <xsl:number count="row" level="single"/>
      </xsl:variable>
      <SaveDataTable>
        <xsl:apply-templates>
          <xsl:with-param name="pkey" select="-1 * $pos"/>
        </xsl:apply-templates>
      </SaveDataTable>
    </xsl:template>

row 元素的每个子元素上,发出一个包含键名称、键值、主键和表单 ID 的 SaveDataTable 元素。

    <xsl:template match="row/*">
      <xsl:param name="pkey"/>
      <KeyName>
        <xsl:value-of select="name()"/>
      </KeyName>
      <KeyValue>
        <xsl:value-of select="."/>
      </KeyValue>
      <PrimaryKey>
        <xsl:value-of select="$pkey"/>
      </PrimaryKey>
      <FormId>
        <xsl:value-of select="$formid"/>
      </FormId>
    </xsl:template>
</xsl:stylesheet>

关于xslt - 如何增加 xslt 中每个节点集的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12063498/

相关文章:

xslt - 是否有 XSL "contains"指令?

xml - XSLT,使用基于属性值的映射表重命名元素

xml - 在XSLT中解析字符串

JSON 到 XSLT : default XML node if JSON element does NOT exist

xml - 为什么 XML 不显示在浏览器中,但在 XML Notepad 2007 (Microsoft) 中正确显示?

xslt - 从 XSL 创建 XSL

json - JSON 到 XML 的 XSLT 3.0 转换 — 数字数据类型

xml - 选择两个节点之间的所有 sibling (不包括 sibling )

c# - 一个umbraco 上的多个网站,需要xslt 宏吗?

xslt 根据拆分和父节点名称生成子节点