考虑这个XML,
XML:
<?xml version="1.0" encoding="UTF-8"?>
<items>
<book>
<title>doublebell</title>
<count>available</count>
</book>
<phone>
<brand>nokia</brand>
<model></model>
</phone>
</items>
编写XSLT时映射标准:
XSLT:
<?xml version="1.0" encoding="ISO-8859-1"?>
<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:variable name="book" select="items/book" />
<xsl:variable name="phone" select="items/phone" />
<xsl:template match="/">
<items>
<newbook>
<xsl:if test="$book/title!=''">
<newtitle>
<xsl:value-of select="$book/title" />
</newtitle>
</xsl:if>
<xsl:if test="$book/count!=''">
<newcount>
<xsl:value-of select="$book/count" />
</newcount>
</xsl:if>
</newbook>
<xsl:if test="$phone/brand!='' or $phone/model!=''"> <!-- not sure if this condition is required for the above mapping criteria -->
<newphone>
<xsl:if test="$phone/brand!=''">
<newbrand>
<xsl:value-of select="$phone/brand" />
</newbrand>
</xsl:if>
<xsl:if test="$phone/model!=''">
<newmodel>
<xsl:value-of select="$phone/model" />
</newmodel>
</xsl:if>
</newphone>
</xsl:if>
</items>
</xsl:template>
</xsl:stylesheet>
这是我关注的问题: - 在我的实际XSLT中,我有近70个条件
这个,每次XPath搜索都进行两次[或三次..]
每个条件[例如:<xsl:if test="$phone/brand!=''">
和<xsl:value-of select="$phone/brand" />
以及外if
条件。
这是多少性能开销?我在运行申请时感觉不到。
如果这是编写XSLT的正确方法,我想听听有经验的人的意见。我是否需要将路径保存在变量中并重复使用$book
和$phone
?在这种情况下,将有70个+变量来保持这个。
答案 0 :(得分:1)
使用模板可以完全不同地解决这个问题。如果您定义的模板匹配任何内容为空且不执行任何操作的元素:
<xsl:template match="*[. = '']" />
或者可能使用normalize-space()
如果要将元素视为空,只要它们只包含空格
<xsl:template match="*[not(normalize-space())]" />
现在有了这个,为你 感兴趣的元素添加模板
<xsl:template match="book">
<newbook><xsl:apply-templates /></newbook>
</xsl:template>
<xsl:template match="title">
<newtitle><xsl:apply-templates /></newtitle>
</xsl:template>
等等。现在,book
模板将创建一个newbook
元素并继续处理其子元素。当它到达title
时,它将有两个不同的模板可供选择,并将选择&#34;最具体的&#34;比赛。如果标题为空,则*[. = '']
模板将获胜并且不输出任何内容,仅当标题为非空时才会创建newtitle
元素。
通过这种方式,您可以让模板匹配器为您完成大部分工作,您不需要使用xsl:if
进行任何明确的条件检查。
<?xml version="1.0" encoding="ISO-8859-1"?>
<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:template match="/">
<items><xsl:apply-templates select="items/*" /></items>
</xsl:template>
<!-- ignore empty elements -->
<xsl:template match="*[not(normalize-space())]" />
<xsl:template match="book">
<newbook><xsl:apply-templates /></newbook>
</xsl:template>
<xsl:template match="title">
<newtitle><xsl:apply-templates /></newtitle>
</xsl:template>
<!-- and so on with similar templates for the other elements -->
</xsl:stylesheet>
答案 1 :(得分:1)
在Ian's answer的基础上,您还可以创建一个通用模板,为您创建“新”元素,而无需单独指定每个元素。这看起来如下所示:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<items><xsl:apply-templates select="items/*" /></items>
</xsl:template>
<xsl:template match="*[not(normalize-space())]" />
<xsl:template match="*">
<xsl:element name="{concat('new',name())}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
最后一个模板只是通过将单词“new”连接到它的前面来重建元素。