XML 輸入:
<a>
<desc key="1" attr1="# {@key}" attr2="{@key} #" attr3="" title="{@attr2}">
<b>
<slot key="2" attr4="{@key}" title="{@attr4} {@attr4}" >
<val key="3">
<fix key="4" title11="{@key} {@key}" title="{@key} {@title11}" >
<c></c>
</fix>
</val>
<numb key="5" title12="z{@key}z in {@key}" title="{@title12} {@key}" titlew="{@title} {@title12}">
</numb>
</slot>
</b>
</desc>
</a>
我有這個 XML 轉換代碼 XSLT1.0:
<?xml version="1.0" encoding="utf-8"?>
<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="*/@*">
<xsl:attribute name="{name()}">
<xsl:call-template name="replace">
<xsl:with-param name="str" select="."/>
<xsl:with-param name="find" select="'{@key}'"/>
<xsl:with-param name="replace" select="../@key"/>
</xsl:call-template>
</xsl:attribute>
</xsl:template>
<!--Identity template-->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template name="replace">
<xsl:param name="str"/>
<xsl:param name="find"/>
<xsl:param name="replace"/>
<xsl:choose>
<xsl:when test="contains($str, $find)">
<xsl:variable name="prefix" select="substring-before($str, $find)"/>
<xsl:variable name="suffix">
<xsl:call-template name="replace">
<xsl:with-param name="str" select="substring-after($str, $find)"/>
<xsl:with-param name="find" select="$find"/>
<xsl:with-param name="replace" select="$replace"/>
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="concat($prefix, $replace, $suffix)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$str"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
此代碼在標記屬性值中查找任何出現的“{@key}”。如果標記在“@”字符之后指定了一個屬性,即在本例中為“key”,則字串“{@key}”將替換為“key”屬性的值。那么轉換后的 XML 檔案將如下所示:
<a>
<desc key="1" attr1="# 1" attr2="1 #" attr3="" title="{@attr2}">
<b>
<slot key="2" attr4="2" title="{@attr4} {@attr4}">
<val key="3">
<fix key="4" title11="4 4" title="4 {@title11}">
<c />
</fix>
</val>
<numb key="5" title12="z5z in 5" title="{@title12} 5" titlew="{@title} {@title12}">
</numb>
</slot>
</b>
</desc>
</a>
但我不僅需要將字串 '{@key}' 替換為 'key' 屬性的值,還需要更一般的規則:如果標簽具有屬性 'attr',則任何出現的字串 '{@值標簽屬性中的 attr}' 被替換為 'attr' 屬性的值。有沒有辦法使用 XSLT 1.0 做到這一點,以便在轉換后 XML 檔案如下所示:
<a>
<desc key="1" attr1="# 1" attr2="1 #" attr3="" title="1 #">
<b>
<slot key="2" attr4="2" title="2 2" >
<val key="3">
<fix key="4" title11="4 4" title="4 4 4" >
<c></c>
</fix>
</val>
<numb key="5" title12="z5z in 5" title="z5z in 5 5" titlew="z5z in 5 5 z5z in 5">
</numb>
</slot>
</b>
</desc>
</a>
uj5u.com熱心網友回復:
如果可以假設屬性永遠不會包含{}字符,而不是包含對同一父元素的另一個屬性的參考,那么您可以執行以下操作:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{name()}">
<xsl:call-template name="expand">
<xsl:with-param name="text" select="."/>
</xsl:call-template>
</xsl:attribute>
</xsl:template>
<xsl:template name="expand">
<xsl:param name="text"/>
<xsl:choose>
<xsl:when test="contains($text, '{') ">
<!-- text before reference -->
<xsl:value-of select="substring-before($text, '{')"/>
<!-- recursive call with the expanded reference-->
<xsl:variable name="name" select="substring-before(substring-after($text, '{@'), '}')" />
<xsl:call-template name="expand">
<xsl:with-param name="text" select="../@*[name()=$name]"/>
</xsl:call-template>
<!-- recursive call with rest of the text -->
<xsl:call-template name="expand">
<xsl:with-param name="text" select="substring-after($text, '}')"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
警告:沒有經過非常徹底的測驗。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/434189.html
