Xml 到attibute的XSLT转换
关于XSLT转换,我有以下问题-我需要转换XML文件,考虑到从父节点到根节点的所有属性值。因此,有这样一个代码(将XY属性视为具有“X,Y”值的字符串):Xml 到attibute的XSLT转换,xml,xslt,Xml,Xslt,关于XSLT转换,我有以下问题-我需要转换XML文件,考虑到从父节点到根节点的所有属性值。因此,有这样一个代码(将XY属性视为具有“X,Y”值的字符串): 我需要一个输出 我尝试使用如下模板使用XSLT转换: 但这是一个解决方案,只适用于一个级别。只有使用XSLT才能进行这种转换吗?如果您使用的是XSLT 1.0,则需要一个递归遍历节点树的模板: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XS
我需要一个输出
我尝试使用如下模板使用XSLT转换:
但这是一个解决方案,只适用于一个级别。只有使用XSLT才能进行这种转换吗?如果您使用的是XSLT 1.0,则需要一个递归遍历节点树的模板:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@XY" mode="sumXOffset" name="SumXOffset">
<xsl:param name="currentValue"
select="substring-before(., ',')" />
<xsl:variable name="sum">
<xsl:apply-templates select="(../ancestor::*/@XY)[last()]" mode="sumXOffset" />
</xsl:variable>
<xsl:value-of select="$currentValue +
concat('0', $sum)" />
</xsl:template>
<xsl:template match="@OffsetX">
<xsl:attribute name="{name()}">
<xsl:call-template name="SumXOffset">
<xsl:with-param name="currentValue" select="." />
</xsl:call-template>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
在示例XML上运行时,结果是:
<Layout XY="40,20">
<Layout XY="0,20">
<Circle OffsetX="40" />
</Layout>
<Circle OffsetX="46" />
<Layout XY="100,20">
<Circle OffsetX="140" />
<Layout XY="200,20">
<Circle OffsetX="345" />
</Layout>
</Layout>
</Layout>
如果有可用的XSLT 2.0处理器,则解决方案要简单得多:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@OffsetX">
<xsl:attribute name="{name()}">
<xsl:value-of select=". + sum(ancestor::*/@XY/substring-before(','))"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
我会这样做: XSLT1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Circle/@OffsetX">
<xsl:variable name="previous-X">
<xsl:for-each select="ancestor::*[@XY]">
<x><xsl:value-of select="substring-before(@XY, ',')"/></x>
</xsl:for-each>
</xsl:variable>
<xsl:attribute name="OffsetX">
<xsl:value-of select=". + sum(exsl:node-set($previous-X)/x)"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
在XSLT1.0中,有一种方法可以在没有递归模板的情况下实现这一点(并不是说这有什么问题!),那就是将运行总数作为参数从一个模板传递到另一个模板。本质上,在标识模板中也使用
newOffsetX
参数
试试这个XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:param name="newOffsetX" select="0" />
<xsl:copy>
<xsl:apply-templates select="@*|node()">
<xsl:with-param name="newOffsetX" select="$newOffsetX + number(substring-before(concat('0', @XY, ','), ','))" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="@OffsetX">
<xsl:param name="newOffsetX" select="0" />
<xsl:attribute name="OffsetX">
<xsl:value-of select="$newOffsetX + number(.)" />
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
(concat('0',@XY','),',',',')之前的有趣表达式
子字符串用于处理没有@XY
属性的节点。当存在@XY
属性时,例如值为“40,20”时,“concat”返回“040,20”,因此X数字在数字上仍然相同。当@XY
不存在时,concat
返回0,
,因此X数为“0”。“但这是一种仅适用于一级以上的解决方案”实际上根本不起作用。OffsetX
属性的父元素是圆元素本身,因此表达式。/@XY
不选择任何内容,并且加法的结果是NaN
。哦,是的,对不起-它应该是“前面的子字符串(../../@XY,,”)”我省略了对这个属性的祖辈的选择,而不是对pruposeNice Exsl:node set或variable method(xslt2),+1。