我正在尝试转换这些数据:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<branch link="1" type="band" value="">
<leaf/>
<branch link="1" type="band/mhz" value="some">
<leaf/>
</branch>
<branch link="1" type="band/other" value="thing">
<leaf/>
</branch>
</branch>
<branch link="1" type="member" value="">
<leaf/>
<branch link="1" type="member/kind" value="a">
<leaf/>
</branch>
</branch>
<branch link="2" type="member" value="">
<leaf/>
<branch link="2" type="member/kind" value="b">
<leaf/>
</branch>
</branch>
</root>
得到这个:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
<branch link="" type="other" value="thing">
<leaf/>
</branch>
<branch link="" type="member-info" value="">
<leaf/>
<branch link="" type="member-info/kind" value="a">
<leaf/>
</branch>
</branch>
<branch link="2" type="member" value="">
<leaf/>
<branch link="2" type="member/kind" value="b">
<leaf/>
</branch>
</branch>
</root>
我正在使用这个XSLT:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes" method="xml"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="branch[starts-with(@name, 'band')]">
<xsl:for-each select="current()/*">
<xsl:if test="@name = 'band/other'">
<xsl:variable name="linkId" select="@link"/>
<xsl:for-each select="../../branch[@link=$linkId and @name='member']">
<branch>
<xsl:attribute name="name">
<xsl:value-of select="replace(@name, 'member', 'member-info')"/>
</xsl:attribute>
<xsl:for-each select="@*[.]">
<xsl:if test="local-name() != 'name'">
<xsl:attribute name="{local-name()}">
<xsl:if test="local-name() != 'link'">
<xsl:value-of select="."/>
</xsl:if>
</xsl:attribute>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="./*">
<branch>
<xsl:attribute name="name">
<xsl:value-of
select="replace(@name, 'member', 'member-info')"/>
</xsl:attribute>
<xsl:for-each select="@*[.]">
<xsl:if test="local-name() != 'name'">
<xsl:attribute name="{local-name()}">
<xsl:if test="local-name() != 'link'">
<xsl:value-of select="."/>
</xsl:if>
</xsl:attribute>
</xsl:if>
</xsl:for-each>
<xsl:apply-templates/>
</branch>
</xsl:for-each>
</branch>
<xsl:apply-templates/>
</xsl:for-each>
<xsl:copy>
<xsl:attribute name="name">
<xsl:value-of select="replace(@name, 'band/', '')"/>
</xsl:attribute>
<xsl:for-each select="@*[.]">
<xsl:if test="local-name() != 'name'">
<xsl:attribute name="{local-name()}">
<xsl:if test="local-name() != 'link'">
<xsl:value-of select="."/>
</xsl:if>
</xsl:attribute>
</xsl:if>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:copy>
</xsl:if>
</xsl:for-each>
</xsl:template>
<xsl:template match="branch[@name='member' and @link='']"/>
</xsl:stylesheet>
所以,我正在尝试:
“向上移动逻辑级别”元素匹配<branch type="band/other">
以获取<branch type="other">
,同时清除link
属性并丢弃父级和其他兄弟级别 - &gt;的确定
然后,对于第1部分中的元素,找到具有相同<branch type="member">
attr的link
。值(例如“1”)并通过将“-info”附加到属性branch
的“成员”值 - &gt;来重命名它们(以及它们的type
子项)的 NOK
保留其他元素 - &gt;的确定
第2部分的问题:
我该如何解决?我是否需要一种不同的方法(命名为tempalted)?
答案 0 :(得分:0)
我认为你可以匹配模板中的元素,只需操作属性:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="branch[.//branch[@type = 'band/other']]">
<xsl:apply-templates select=".//branch[@type = 'band/other']"/>
</xsl:template>
<xsl:template match="branch[@type = 'band/other']/@type">
<xsl:attribute name="type" select="replace(., 'band/', '')"/>
</xsl:template>
<xsl:template match="branch[@type = 'band/other']/@link | branch[@type[starts-with(., 'member')] and @link = //branch[@type = 'band/other']/@link]/@link">
<xsl:attribute name="link"></xsl:attribute>
</xsl:template>
<xsl:template match="branch[@type[starts-with(., 'member')] and @link = //branch[@type = 'band/other']/@link]/@type">
<xsl:attribute name="member" select="replace(., 'member', 'member-info')"/>
</xsl:template>
</xsl:transform>
http://xsltransform.net/94AbWC3/1
使用XSLT 3,我们可以将值存储在变量中,并使用键来查找引用的项目:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
version="3.0">
<xsl:variable name="change" select="//branch[@type = 'band/other']"/>
<xsl:key name="ref" match="branch[@type[starts-with(., 'member')]]" use="@link"/>
<xsl:variable name="change-ref" select="key('ref', $change/@link)"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="branch[.//branch[@type = 'band/other']]">
<xsl:apply-templates select=".//branch[@type = 'band/other']"/>
</xsl:template>
<xsl:template match="$change/@type">
<xsl:attribute name="type" select="replace(., 'band/', '')"/>
</xsl:template>
<xsl:template match="$change/@link | $change-ref/@link">
<xsl:attribute name="link"></xsl:attribute>
</xsl:template>
<xsl:template match="$change-ref/@type">
<xsl:attribute name="member" select="replace(., 'member', 'member-info')"/>
</xsl:template>
</xsl:stylesheet>