我想生成一个像这个例子的HTML文件:
英
En Lorem ipsum dolor sit amet,consectetur adipiscing elit。
Nunc rutrum,eros sit amet ornare faucibus。
的问题
Fr Lorem ipsum dolor坐下来,精神恍惚。
Nunc rutrum,eros sit amet ornare faucibus。
从以下示例XML源代码中,我无法控制:
<?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>
所以我写了这个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>
也就是说,我的解决方案感觉非常冗长,但似乎能够实现有用的组合和重用度属性,这对我来说是非常重要的两件事,因为我需要转换许多结构与此示例类似的XML文档;因此,如果我的大多数XSLT都可以重用其他XSLT的部分,那么这将是非常有用的。
一些感兴趣的注释:
所以我想了解一下,我的解决方案对于XSLT争论者看起来是反本能的 - 甚至是错误的。
答案 0 :(得分:1)
我就是这样写的:
<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>
备注:强>
答案 1 :(得分:1)
此转换不包含任何条件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>
应用于提供的XML文档:
<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>
请注意:
使用模板和模式匹配。
使用 <xsl:apply-templates>
在模板的匹配模式中使用谓词,并在<xsl:apply-templates>