我有动态的xml文件。有许多元素,有些可能有属性或可能没有。这是在xsd文件中定义的。
我正在使用递归方法(for-each)逐个显示节点内容。但是,如果任何标签具有任何属性,则条件不匹配,并且不显示该标签的内容。
我想检查当前元素是否具有任何属性。如果还有显示内容,否则也显示标签的内容。
我的xslt代码:
<xsl:template match="node()" mode="chapter">
<xsl:for-each select="node()">
<xsl:if test="current()[name() = 'CHAPTER']">
<fo:block>
<xsl:apply-templates select="current()[name() = 'CHAPTER']" mode="chapter" />
</fo:block>
</xsl:if>
</xsl:for-each>
</xsl:template>
在上面的代码中,在一个xml输入中,CHAPTER标签有一个属性。因此if条件变为false并且它不会进入if块,尽管当前节点是CHAPTER。
我想检查CHAPTER是否有任何属性。 请建议。
提前谢谢。
答案 0 :(得分:3)
您可以在条件中添加另一个谓词,例如:
<xsl:if test="name() = 'CHAPTER' and not(@*)">
这不会处理具有属性的CHAPTER
个节点。
答案 1 :(得分:1)
你的代码看起来有点过于复杂了。您有一个匹配任何节点的模板,然后在每个子节点上循环,然后测试它是否为CHAPTER
,然后您似乎在CHAPTER
上应用其他模板。因此,您的模板并没有真正做任何特别有用的事情,并且很难遵循业务逻辑。
我认为你应该以模式身份转换风格的方式来编写它,你可以创建模板来处理你感兴趣的部分或扔掉你不感兴趣的部分。通过做这样的事情,您上面的模板可能看起来更像:
<xsl:template match="CHAPTER">
<fo:block>
<!-- anything else related specifically to CHAPTER element here -->
<!-- process children of chapter using other templates... -->
<xsl:apply-templates/>
</fo:block>
</xsl:template>
如果您只想处理没有属性的CHAPTER
元素,可以使用:
<xsl:template match="CHAPTER[not(@*)]">
<fo:block>
<!-- anything else related specifically to CHAPTER element here -->
<!-- process children of chapter using other templates... -->
<xsl:apply-templates/>
</fo:block>
</xsl:template>
在上面的模板中,您将处理与CHAPTER直接相关的所有内容,然后您将定义子模板以处理您感兴趣的其他元素/节点。这会将您的代码分解为很简单的部分,例如:
<xsl:template match="CHAPTER[not(@*)]">
<fo:block>
<!-- anything else related specifically to CHAPTER element here -->
<!-- process children of CHAPTER element using other templates... -->
<xsl:apply-templates/>
</fo:block>
</xsl:template>
<xsl:template match="TITLE">
<fo:block font-size="18pt" font-family="sans-serif">
<xsl:copy-of select="text()"/>
</fo:block>
</xsl:template>
<xsl:template match="SYNOPSIS">
<!-- we are not interested in the SYNOPSIS, so do nothing! -->
<xsl:template>
<!-- identity transform driver -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
在上面我想象你的CHAPTER
元素也可能有TITLE
个子元素,并且你可能想要在另一个fo:block
中输出它们。我还想象你的CHAPTER
元素可能有一个SYNOPSIS
子元素,你想忽略它并且不会产生任何输出。
您还可以通过Googling for XSLT身份转换找到这种XSLT编码风格的大量其他示例。