我有这个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>
答案 0 :(得分:2)
另一种方法(以'推'而不是'拉'式)会将处理分解为模板:
<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>
答案 1 :(得分:0)
你可以尝试这个解决方案,但我认为它效率低于你的解决方案:
<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"/>
<xsl:template match="/root">
<DocumentElement>
<xsl:apply-templates select="row/*"/>
</DocumentElement>
</xsl:template>
<xsl:template match="*">
<SaveDataTable>
<KeyName>
<xsl:value-of select="name()"/>
</KeyName>
<KeyValue>
<xsl:value-of select="."/>
</KeyValue>
<PrimaryKey>
<xsl:value-of select="-1 * (count(../preceding-sibling::row) + 1)"/>
</PrimaryKey>
<FormId>
<xsl:value-of select="$formid"/>
</FormId>
</SaveDataTable>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:0)
推送样式解决方案 - 类似于C. M. Sperberg-McQueen,但可能略高一些,因为没有计算xsl:number
并且位置作为参数传递。
另一个不同之处在于我们不需要在任何模板上指定priority
属性。
另外,我们不要乘以-1。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pFormid" select="60202"/>
<xsl:template match="/*">
<DocumentElement>
<xsl:apply-templates/>
</DocumentElement>
</xsl:template>
<xsl:template match="row">
<xsl:apply-templates select="*">
<xsl:with-param name="pPos" select="position()"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="row/*">
<xsl:param name="pPos"/>
<SaveDataTable>
<KeyName>
<xsl:value-of select="name()"/>
</KeyName>
<KeyValue>
<xsl:value-of select="."/>
</KeyValue>
<PrimaryKey>
<xsl:value-of select="-$pPos"/>
</PrimaryKey>
<FormId>
<xsl:value-of select="$pFormid"/>
</FormId>
</SaveDataTable>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<root>
<row>
<number>1001461</number>
<unit>CAN</unit>
</row>
<row>
<number>1001462</number>
<unit>KG</unit>
</row>
</root>
产生了想要的正确结果:
<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>