我正在研究XSLT,我需要在其中实现如下内容.My Source XML示例如下所示.
<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>
<cd>
<title>A</title>
<title>B</title>
<title>C</title>
</cd>
</catalog>
Run Code Online (Sandbox Code Playgroud)
考虑有一些关键值对列表.
Key Value
A Algebra
B Biology
C Chemistry
D Data Analysis
--- ---
---- ---
Run Code Online (Sandbox Code Playgroud)
我需要编写一个xslt,以便每次出现键'A'时,需要用适当的值替换.
我还需要在同一个XSLT中提到Key值对的列表.样本输出:
<Data>
<Subject>Algebra</Subject>
<Subject>Biology</Subject>
<Subject>Chemistry</Subject>
</Data>
Run Code Online (Sandbox Code Playgroud)
任何人都可以帮助我如何做到这一点.
谢谢.
Dim*_*hev 16
I.简单的XSLT 1.0解决方案
这种转变:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:codes>
<code key="A" value="Algebra"/>
<code key="B" value="Biology"/>
<code key="C" value="Chemistry"/>
<code key="D" value="Data Analysis"/>
</my:codes>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"title/text()[. = document('')/*/my:codes/*/@key]">
<xsl:value-of select=
"document('')/*/my:codes/*[@key=current()]/@value"/>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
当应用于提供的XML文档时:
<catalog>
<cd>
<title>A</title>
<title>B</title>
<title>C</title>
</cd>
</catalog>
Run Code Online (Sandbox Code Playgroud)
产生想要的,正确的结果:
<catalog>
<cd>
<title>Algebra</title>
<title>Biology</title>
<title>Chemistry</title>
</cd>
</catalog>
Run Code Online (Sandbox Code Playgroud)
说明:
这是将内联XML节点作为xsl:stylesheet属于(非空)命名空间的全局元素(子元素)的标准方法,不同于xsl命名空间.
II.更高效的XSLT 1.0解决方案,使用密钥:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:codes>
<code key="A" value="Algebra"/>
<code key="B" value="Biology"/>
<code key="C" value="Chemistry"/>
<code key="D" value="Data Analysis"/>
</my:codes>
<xsl:key name="kCodeByName" match="code" use="@key"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"title/text()[. = document('')/*/my:codes/*/@key]">
<xsl:variable name="vCur" select="."/>
<xsl:for-each select="document('')">
<xsl:value-of select=
"key('kCodeByName', $vCur)/@value"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
当此转换应用于同一XML文档(上面)时,会产生相同的正确的想要结果:
<catalog>
<cd>
<title value="Algebra"/>
<title value="Biology"/>
<title value="Chemistry"/>
</cd>
</catalog>
Run Code Online (Sandbox Code Playgroud)
说明:
通过key()函数访问数据通常是次线性的 - 通常是O(1)并且比线性搜索快得多(如果要搜索的节点数量很大,这很重要).
xsl:key如果包含要查找的节点的文档是当前文档,则在处理另一文档的节点时通过索引()访问一个文档的节点是可能的.要从其他文档访问节点,需要保存其根(或感兴趣的节点并从变量引用).
III.XSLT 2.0解决方案:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vCodes">
<codes>
<code key="A" value="Algebra"/>
<code key="B" value="Biology"/>
<code key="C" value="Chemistry"/>
<code key="D" value="Data Analysis"/>
</codes>
</xsl:variable>
<xsl:key name="kCodeByName" match="code" use="string(@key)"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"title/text()[key('kCodeByName', ., $vCodes)]">
<xsl:sequence select=
"key('kCodeByName', ., $vCodes)/@value"/>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
当此转换应用于同一XML文档(上面)时,会产生相同的正确的想要结果:
<catalog>
<cd>
<title value="Algebra"/>
<title value="Biology"/>
<title value="Chemistry"/>
</cd>
</catalog>
Run Code Online (Sandbox Code Playgroud)
说明:
与高效的XSLT 1.0解决方案几乎相同,但是:
在XSLT 2.0中,模板匹配模式可以包含变量引用.
在XSLT 2.0中,不需要操纵当前和索引文档的特技技巧 - key()函数的第三个参数是指定要使用其索引的树.
| 归档时间: |
|
| 查看次数: |
8519 次 |
| 最近记录: |