我需要根据属性增加xslt中的值。假设我的xml像这样,
<comp>
<fig xml:id="c1-fig-001"/>
<fig xml:id="c1-fig-002"/>
<fig xml:id="c1-fig-003"/>
<fig xml:id="c1-fig-004" resumeatnum="7"/>
<fig xml:id="c1-fig-005"/>
<fig xml:id="c1-fig-006"/>
<fig xml:id="c1-fig-007" resumeatnum="18"/>
<fig xml:id="c1-fig-008"/>
<fig xml:id="c1-fig-009"/>
</comp>
我需要像这样的输出,
<comp>
<fig xml:id="c1-fig-001"/>
<fignum>1.1</fignum>
<fig xml:id="c1-fig-002"/>
<fignum>1.2</fignum>
<fig xml:id="c1-fig-003"/>
<fignum>1.3</fignum>
<fig xml:id="c1-fig-004" resumeatnum="7"/>
<fignum>1.7</fignum>
<fig xml:id="c1-fig-005"/>
<fignum>1.8</fignum>
<fig xml:id="c1-fig-006"/>
<fignum>1.9</fignum>
<fig xml:id="c1-fig-007" resumeatnum="18"/>
<fignum>1.18</fignum>
<fig xml:id="c1-fig-008"/>
<fignum>1.19</fignum>
<fig xml:id="c1-fig-009"/>
<fignum>1.20</fignum>
</comp>
我需要从xml:id
中获取1
属性的值,以及c1
之后的数字中的另一个数字。
如果有属性fig
,那么我需要使用该值而不是正常值,并增加以下节点的值。请提供xslt来执行此操作。
答案 0 :(得分:1)
以下XSLT 2.0样式表:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:template match="comp">
<xsl:for-each-group select="fig" group-starting-with="*[@resumeatnum]">
<xsl:variable name="base" select="(@resumeatnum, 1)[1] - 1"/>
<xsl:for-each select="current-group()">
<xsl:copy-of select="."/>
<fignum>1.<xsl:value-of select="position()+$base"/></fignum>
</xsl:for-each>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
产生以下输出:
<?xml version="1.0" encoding="UTF-8"?>
<fig xml:id="c1-fig-001"/>
<fignum>1.1</fignum>
<fig xml:id="c1-fig-002"/>
<fignum>1.2</fignum>
<fig xml:id="c1-fig-003"/>
<fignum>1.3</fignum>
<fig xml:id="c1-fig-004" resumeatnum="7"/>
<fignum>1.7</fignum>
<fig xml:id="c1-fig-005"/>
<fignum>1.8</fignum>
<fig xml:id="c1-fig-006"/>
<fignum>1.9</fignum>
<fig xml:id="c1-fig-007" resumeatnum="18"/>
<fignum>1.18</fignum>
<fig xml:id="c1-fig-008"/>
<fignum>1.19</fignum>
<fig xml:id="c1-fig-009"/>
<fignum>1.20</fignum>
答案 1 :(得分:1)
这是一个较短的(33个格式良好的短线)和更简单的XSLT 1.0解决方案(三个短模板,没有substring()
,没有substring-before()
,没有复杂和长的多线表达式,没有concat()
,没有xsl:for-each
,没有xsl:if
,没有xsl:variable
,没有string-length()
,没有xsl:call-template
:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kFollowing" match="fig[not(@resumeatnum)]"
use="generate-id((preceding-sibling::*[@resumeatnum][1]
|
..
)[last()]
)"/>
<xsl:template match="/*">
<comp>
<xsl:apply-templates select="key('kFollowing', generate-id())"/>
<xsl:apply-templates select="fig[@resumeatnum]"/>
</comp>
</xsl:template>
<xsl:template match="fig">
<xsl:param name="pStart" select="1"/>
<fig xml:id="{@xml:id}"/>
<fignum>1.<xsl:value-of select="position() + $pStart -1"/></fignum>
</xsl:template>
<xsl:template match="fig[@resumeatnum]">
<fig xml:id="{@xml:id}" resumeatnum="{@resumeatnum}"/>
<fignum>1.<xsl:value-of select="@resumeatnum"/></fignum>
<xsl:apply-templates select="key('kFollowing', generate-id())">
<xsl:with-param name="pStart" select="@resumeatnum+1"/>
</xsl:apply-templates>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档时:
<comp>
<fig xml:id="c1-fig-001"/>
<fig xml:id="c1-fig-002"/>
<fig xml:id="c1-fig-003"/>
<fig xml:id="c1-fig-004" resumeatnum="7"/>
<fig xml:id="c1-fig-005"/>
<fig xml:id="c1-fig-006"/>
<fig xml:id="c1-fig-007" resumeatnum="18"/>
<fig xml:id="c1-fig-008"/>
<fig xml:id="c1-fig-009"/>
</comp>
产生了想要的正确结果:
<comp>
<fig xml:id="c1-fig-001"/>
<fignum>1.1</fignum>
<fig xml:id="c1-fig-002"/>
<fignum>1.2</fignum>
<fig xml:id="c1-fig-003"/>
<fignum>1.3</fignum>
<fig xml:id="c1-fig-004" resumeatnum="7"/>
<fignum>1.7</fignum>
<fig xml:id="c1-fig-005"/>
<fignum>1.8</fignum>
<fig xml:id="c1-fig-006"/>
<fignum>1.9</fignum>
<fig xml:id="c1-fig-007" resumeatnum="18"/>
<fignum>1.18</fignum>
<fig xml:id="c1-fig-008"/>
<fignum>1.19</fignum>
<fig xml:id="c1-fig-009"/>
<fignum>1.20</fignum>
</comp>
答案 2 :(得分:0)
这样的事情可能会起作用
<xsl:for-each select="/comp/fig">
<fignum>1.<xsl:value-of select="substring(@xml:id,string-length(@xml:id),1)"/>1</fignum>
</xsl:for-each>
暂时没有使用xslt / xpath所以可能不完美。基本上只是循环通过无花果节点和子串最后一个字符。如果要循环使用超过9个节点,则必须更改子字符串以获取所有数字
答案 3 :(得分:0)
PigChicken,我认为他要求根据之前的[if existing] resumeatnum属性修改自动增量功能。通过为主要和次要版本组件创建变量,然后将简历中的“偏移量”添加到相应的次要版本,以下内容适用于给定示例。例如,resumeatnum为18,次要版本为7,偏移量为11,也会添加到以下次要版本中。我使用了number()强制转换,并且可能会删除其中的一些。这是变换:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.1" exclude-result-prefixes="" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>
<xsl:template match="/comp">
<comp>
<xsl:for-each select="./fig">
<xsl:copy-of select="."/>
<xsl:variable name="major">
<xsl:value-of select="substring-after(substring-before(./@xml:id,'-'),'c')"/>
</xsl:variable>
<xsl:variable name="minor">
<xsl:value-of select="number(substring-after(./@xml:id,'fig-'))"/>
</xsl:variable>
<xsl:variable name="resume_offset">
<xsl:if test="./@resumeatnum">
<xsl:value-of select="number(./@resumeatnum - $minor)"/>
</xsl:if>
<xsl:if test="not(./@resumeatnum)">
<xsl:if test="./preceding-sibling::*[@resumeatnum]">
<xsl:value-of select="number(./preceding-sibling::*[@resumeatnum][1]/@resumeatnum) - number(substring-after(./preceding-sibling::*[@resumeatnum][1]/@xml:id,'fig-'))"/>
</xsl:if>
<xsl:if test="not(./preceding-sibling::*[@resumeatnum])">
<xsl:value-of select="number(0)"/>
</xsl:if>
</xsl:if>
</xsl:variable>
<fignum>
<xsl:value-of select="$major"/>
<xsl:text>.</xsl:text>
<xsl:value-of select="$minor+$resume_offset"/>
</fignum>
</xsl:for-each>
</comp>
</xsl:template>
</xsl:stylesheet>
答案 4 :(得分:0)
另一种方法是首先匹配第一个 fig 元素
<xsl:apply-templates select="fig[1]"/>
然后你有一个主模板来匹配 fig 元素,但是有一个参数可以保存'递增'值。请注意,它也充当命名模板。
<xsl:template match="fig" name="fig">
<xsl:param name="sequence" select="1"/>
在此范围内,您可以输出 fignum 元素
<fignum>
<xsl:value-of
select="concat(substring-before(substring(@xml:id, 2, string-length(@xml:id) - 1), '-'), '.', $sequence)"/>
</fignum>
然后你会匹配下一个 fig 元素,增加参数的值
<xsl:apply-templates select="following-sibling::fig[1]">
<xsl:with-param name="sequence" select="$sequence + 1"/>
</xsl:apply-templates>
要重置序列,您只需要一个匹配 fig 元素的模板,这些元素具有相关属性,您只需使用属性值调用命名模板即可覆盖它
<xsl:template match="fig[@resumeatnum != '']">
<xsl:call-template name="fig">
<xsl:with-param name="sequence" select="@resumeatnum"/>
</xsl:call-template>
</xsl:template>
这是完整的XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="comp">
<comp>
<xsl:apply-templates select="fig[1]"/>
</comp>
</xsl:template>
<xsl:template match="fig[@resumeatnum != '']">
<xsl:call-template name="fig">
<xsl:with-param name="sequence" select="@resumeatnum"/>
</xsl:call-template>
</xsl:template>
<xsl:template match="fig" name="fig">
<xsl:param name="sequence" select="1"/>
<fig>
<xsl:apply-templates select="@*"/>
<fignum>
<xsl:value-of select="concat(substring-before(substring(@xml:id, 2, string-length(@xml:id) - 1), '-'), '.', $sequence)"/>
</fignum>
</fig>
<xsl:apply-templates select="following-sibling::fig[1]">
<xsl:with-param name="sequence" select="$sequence + 1"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当应用于您的示例XML时,输出以下内容
<comp>
<fig xml:id="c1-fig-001">
<fignum>1.1</fignum>
</fig>
<fig xml:id="c1-fig-002">
<fignum>1.2</fignum>
</fig>
<fig xml:id="c1-fig-003">
<fignum>1.3</fignum>
</fig>
<fig xml:id="c1-fig-004" resumeatnum="7">
<fignum>1.7</fignum>
</fig>
<fig xml:id="c1-fig-005">
<fignum>1.8</fignum>
</fig>
<fig xml:id="c1-fig-006">
<fignum>1.9</fignum>
</fig>
<fig xml:id="c1-fig-007" resumeatnum="18">
<fignum>1.18</fignum>
</fig>
<fig xml:id="c1-fig-008">
<fignum>1.19</fignum>
</fig>
<fig xml:id="c1-fig-009">
<fignum>1.20</fignum>
</fig>
</comp>