Xslt 基于属性对多个同级重新排序
我想生成一个HTML文件,如以下示例所示: 英语 这是一位伟大的精英 努克·鲁特鲁姆,爱神坐在阿梅特·奥纳雷·福西布斯身边 法国 神父Lorem ipsum dolor sit amet,献祭精英 努克·鲁特鲁姆,爱神坐在阿梅特·奥纳雷·福西布斯身边 来自以下示例XML源,对此我没有控制权:Xslt 基于属性对多个同级重新排序,xslt,Xslt,我想生成一个HTML文件,如以下示例所示: 英语 这是一位伟大的精英 努克·鲁特鲁姆,爱神坐在阿梅特·奥纳雷·福西布斯身边 法国 神父Lorem ipsum dolor sit amet,献祭精英 努克·鲁特鲁姆,爱神坐在阿梅特·奥纳雷·福西布斯身边 来自以下示例XML源,对此我没有控制权: <?xml version="1.0" encoding="ISO-8859-1"?> <content id=""> <header language="en"&g
<?xml version="1.0" encoding="ISO-8859-1"?>
<content id="">
<header language="en">
<enabled>true</enabled>
<img src="http://i.stack.imgur.com/xGCNw.gif" />
<!-- more header-related elements -->
</header>
<header language="fr">
<enabled>false</enabled>
<img src="" />
<!-- more header-related elements -->
</header>
<html language="en" type="source">
<![CDATA[
<p>En Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
]]>
</html>
<html language="fr" type="source">
<![CDATA[
<p>Fr Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
]]>
</html>
</content>
真的
假的
这是一位伟大的精英
努克·鲁特鲁姆,爱神坐在阿梅特·奥纳雷·福西布斯身边
]]>
神父Lorem ipsum dolor sit amet,献祭精英
努克·鲁特鲁姆,爱神坐在阿梅特·奥纳雷·福西布斯身边
]]>
所以我写了这个XSLT来实现这一点:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<h1>English</h1>
<hr/>
<xsl:for-each select="content/header">
<xsl:call-template name="header">
<xsl:with-param name="lang">en</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
<xsl:for-each select="content/html">
<xsl:call-template name="html">
<xsl:with-param name="lang">en</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
<hr/>
<h1>Français</h1>
<hr/>
<xsl:for-each select="content/header">
<xsl:call-template name="header">
<xsl:with-param name="lang">fr</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
<xsl:for-each select="content/html">
<xsl:call-template name="html">
<xsl:with-param name="lang">fr</xsl:with-param>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="header" match="*">
<xsl:param name='lang'/>
<xsl:if test="current()[@language=$lang]">
<xsl:if test="enabled[normalize-space(text())='true']">
<xsl:call-template name="image"/>
<!-- more header-related elements -->
</xsl:if>
</xsl:if>
</xsl:template>
<xsl:template name="image" match="*">
<xsl:if test="img[not(normalize-space(@src)='')]">
<xsl:copy-of select="img"/>
</xsl:if>
</xsl:template>
<xsl:template name="html" match="*">
<xsl:param name='lang'/>
<xsl:if test="current()[@language=$lang]">
<xsl:value-of select="node()" disable-output-escaping="yes" />
</xsl:if>
</xsl:template>
</xsl:stylesheet>
英语
EN
EN
法国
fr
fr
这就是说,我的解决方案感觉非常冗长,但似乎支持有用的组合和重用属性,这两个属性对我来说非常重要,因为我将需要转换大量结构类似于此示例的XML文档;因此,如果我的大多数XSLT可以重用其他XSLT的一部分,这将非常有用
几点注意事项:
- 转换速度并不重要,尽管在这方面了解更多可能会很有趣
- 转换将永远不需要处理编码超过两种示例语言(en和fr)的XML文档
因此,我想了解我的解决方案在您看来是否反惯用,甚至是完全错误的,XSLT争论者。我会这样写:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my"
exclude-result-prefixes="my">
<xsl:output method="html" indent="yes"/>
<my:language-labels>
<lang code="en" label="English"/>
<lang code="fr" label="Francais"/>
</my:language-labels>
<xsl:template match="/*">
<xsl:apply-templates select="header"/>
</xsl:template>
<xsl:template match="header">
<xsl:variable name="curLang" select="@language"/>
<h1>
<xsl:value-of select="document('')/*/my:language-labels/lang[@code = $curLang]/@label"/>
</h1>
<hr/>
<xsl:copy-of select="img[not(normalize-space(@src) = '')][../enabled[normalize-space() = 'true']]"/>
<xsl:value-of select="../html[@language = $curLang]" disable-output-escaping="yes"/>
</xsl:template>
</xsl:stylesheet>
您的HTML示例看起来已损坏,因此我可能有点错误。我的结果是:
<h1>English</h1>
<hr>
<img src="http://i.stack.imgur.com/xGCNw.gif">
<p>En Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
<h1>Francais</h1>
<hr>
<p>Fr Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
英语
这是一位伟大的精英
努克·鲁特鲁姆,爱神坐在阿梅特·奥纳雷·福西布斯身边
法兰西
神父Lorem ipsum dolor sit amet,献祭精英
努克·鲁特鲁姆,爱神坐在阿梅特·奥纳雷·福西布斯身边
注意事项:
此转换不包含任何条件XSLT指令或任何命名模板:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" exclude-result-prefixes="my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<my:langs>
<lang short="en">English</lang>
<lang short="fr">Français</lang>
</my:langs>
<xsl:variable name="vLangs" select="document('')/*/my:langs/*"/>
<xsl:template match="header">
<xsl:apply-templates select="node()|@*"/>
<hr/>
<xsl:apply-templates select=
"../html[@language=current()/@language]/text()"/>
</xsl:template>
<xsl:template match="header/@language">
<h1><xsl:value-of select="$vLangs[@short=current()]"/></h1>
</xsl:template>
<xsl:template match="header[enabled='true']/img[@src and not(@src='')]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="html/text()">
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>
<xsl:template match="html|text()"/>
</xsl:stylesheet>
<content id="">
<header language="en">
<enabled>true</enabled>
<img src="http://i.stack.imgur.com/xGCNw.gif" />
<!-- more header-related elements -->
</header>
<header language="fr">
<enabled>false</enabled>
<img src="" />
<!-- more header-related elements -->
</header>
<html language="en" type="source">
<![CDATA[
<p>En Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
]]>
</html>
<html language="fr" type="source">
<![CDATA[
<p>Fr Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
]]>
</html>
</content>
<h1>English</h1>
<img src="http://i.stack.imgur.com/xGCNw.gif" />
<hr />
<p>En Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
<h1>Français</h1>
<hr />
<p>Fr Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
英语
法国
应用于提供的XML文档时:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" exclude-result-prefixes="my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<my:langs>
<lang short="en">English</lang>
<lang short="fr">Français</lang>
</my:langs>
<xsl:variable name="vLangs" select="document('')/*/my:langs/*"/>
<xsl:template match="header">
<xsl:apply-templates select="node()|@*"/>
<hr/>
<xsl:apply-templates select=
"../html[@language=current()/@language]/text()"/>
</xsl:template>
<xsl:template match="header/@language">
<h1><xsl:value-of select="$vLangs[@short=current()]"/></h1>
</xsl:template>
<xsl:template match="header[enabled='true']/img[@src and not(@src='')]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="html/text()">
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>
<xsl:template match="html|text()"/>
</xsl:stylesheet>
<content id="">
<header language="en">
<enabled>true</enabled>
<img src="http://i.stack.imgur.com/xGCNw.gif" />
<!-- more header-related elements -->
</header>
<header language="fr">
<enabled>false</enabled>
<img src="" />
<!-- more header-related elements -->
</header>
<html language="en" type="source">
<![CDATA[
<p>En Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
]]>
</html>
<html language="fr" type="source">
<![CDATA[
<p>Fr Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
]]>
</html>
</content>
<h1>English</h1>
<img src="http://i.stack.imgur.com/xGCNw.gif" />
<hr />
<p>En Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
<h1>Français</h1>
<hr />
<p>Fr Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
真的
假的
这是一位伟大的精英
努克·鲁特鲁姆,爱神坐在阿梅特·奥纳雷·福西布斯身边
]]>
神父Lorem ipsum dolor sit amet,献祭精英
努克·鲁特鲁姆,爱神坐在阿梅特·奥纳雷·福西布斯身边
]]>
生成所需的正确结果:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" exclude-result-prefixes="my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<my:langs>
<lang short="en">English</lang>
<lang short="fr">Français</lang>
</my:langs>
<xsl:variable name="vLangs" select="document('')/*/my:langs/*"/>
<xsl:template match="header">
<xsl:apply-templates select="node()|@*"/>
<hr/>
<xsl:apply-templates select=
"../html[@language=current()/@language]/text()"/>
</xsl:template>
<xsl:template match="header/@language">
<h1><xsl:value-of select="$vLangs[@short=current()]"/></h1>
</xsl:template>
<xsl:template match="header[enabled='true']/img[@src and not(@src='')]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="html/text()">
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>
<xsl:template match="html|text()"/>
</xsl:stylesheet>
<content id="">
<header language="en">
<enabled>true</enabled>
<img src="http://i.stack.imgur.com/xGCNw.gif" />
<!-- more header-related elements -->
</header>
<header language="fr">
<enabled>false</enabled>
<img src="" />
<!-- more header-related elements -->
</header>
<html language="en" type="source">
<![CDATA[
<p>En Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
]]>
</html>
<html language="fr" type="source">
<![CDATA[
<p>Fr Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
]]>
</html>
</content>
<h1>English</h1>
<img src="http://i.stack.imgur.com/xGCNw.gif" />
<hr />
<p>En Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
<h1>Français</h1>
<hr />
<p>Fr Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
英语
这是一位伟大的精英
努克·鲁特鲁姆,爱神坐在阿梅特·奥纳雷·福西布斯身边
法国
神父Lorem ipsum dolor sit amet,献祭精英
努克·鲁特鲁姆,爱神坐在阿梅特·奥纳雷·福西布斯身边
注意事项:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my" exclude-result-prefixes="my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<my:langs>
<lang short="en">English</lang>
<lang short="fr">Français</lang>
</my:langs>
<xsl:variable name="vLangs" select="document('')/*/my:langs/*"/>
<xsl:template match="header">
<xsl:apply-templates select="node()|@*"/>
<hr/>
<xsl:apply-templates select=
"../html[@language=current()/@language]/text()"/>
</xsl:template>
<xsl:template match="header/@language">
<h1><xsl:value-of select="$vLangs[@short=current()]"/></h1>
</xsl:template>
<xsl:template match="header[enabled='true']/img[@src and not(@src='')]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="html/text()">
<xsl:value-of select="." disable-output-escaping="yes"/>
</xsl:template>
<xsl:template match="html|text()"/>
</xsl:stylesheet>
<content id="">
<header language="en">
<enabled>true</enabled>
<img src="http://i.stack.imgur.com/xGCNw.gif" />
<!-- more header-related elements -->
</header>
<header language="fr">
<enabled>false</enabled>
<img src="" />
<!-- more header-related elements -->
</header>
<html language="en" type="source">
<![CDATA[
<p>En Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
]]>
</html>
<html language="fr" type="source">
<![CDATA[
<p>Fr Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
]]>
</html>
</content>
<h1>English</h1>
<img src="http://i.stack.imgur.com/xGCNw.gif" />
<hr />
<p>En Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
<h1>Français</h1>
<hr />
<p>Fr Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Nunc rutrum, eros sit amet ornare faucibus.</p>
您编写的[它]似乎支持有用的合成和重用属性。对于那些CDATA部分,我不这么认为……是的,但我无法控制XML源:\好问题,+1。请参阅我的答案,了解不使用任何xslt条件指令和任何命名模板的解决方案。看看这是否有助于您非常简洁!!!非常感谢您的回答和注释。虽然我接受了@Dimitre Novatchev的回答,但我仍然使用了您的一些见解和技巧。我非常喜欢您所提供的模式匹配。这使得模板非常模块化。非常感谢您的回答。奇怪的是,这段代码
使我以前基于xalan的实现失败,出现了NullPointerException
。(还有@Flack的等效代码。)因此,在升级XSLT处理器之前,我跳过了sweet变量的用法,只输出语言的短名称。@Daniel Jomphe:解决方法是:
@Dimitre Novatchev:我尝试了,但没有成功。谢谢你的努力。