如果不应从转换中删除元素,我想向元素添加属性。我认为我当前的XSL会满足这个要求,首先丢弃所有不在allowedArticles变量中的元素,然后将属性添加到剩下的元素中。
然而,这不起作用,我不确定如何正确地做到这一点。我想两者都做,如果没有在allowedArticles中,则丢弃整个元素,如果它应该在转换中,则添加一个属性。
有人能指出我正确的方向吗?
这是我的示例XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:escenic="http://xmlns.escenic.com/2009/import">
<xsl:output omit-xml-declaration="no" indent="yes"/>
<xsl:strip-space elements="*" />
<!-- Fetch the array from an external file: allowedArticles.xml -->
<xsl:variable
name="allowedArticles"
select="document('allowedArticles.xml')/allowedArticles/articleId" />
<!-- Identity template, copies every element in source file -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<!-- Matches content items that are NOT in the allowedArticles array,
and discards them by doing nothing-->
<xsl:template match="escenic:escenic/escenic:content[not(@exported-dbid=$allowedArticles)]" />
<!-- Removes section-ref elements from within content elements -->
<xsl:template match="escenic:escenic/escenic:content/escenic:section-ref" />
<!-- Add delete-relations attribute to all content elements -->
<xsl:template match="escenic:escenic/escenic:content">
<xsl:copy>
<xsl:attribute name="delete-relations">
<xsl:value-of select="'true'" />
</xsl:attribute>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:1)
您的第二个模板会删除您不想要的文章,但您的上一个模板似乎会再次处理所有这些文章。您可以通过添加谓词来解决此问题:
<xsl:template match="escenic:escenic/escenic:content[@exported-dbid=$allowedArticles]">
<xsl:copy>
<xsl:attribute name="delete-relations">
<xsl:value-of select="'true'" />
</xsl:attribute>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
答案 1 :(得分:1)
考虑以下两个模板规则:
<xsl:template match="escenic:escenic/escenic:content
[not(@exported-dbid=$allowedArticles)]" />
<xsl:template match="escenic:escenic/escenic:content">
虽然您和我很明显第一条规则匹配第二条规则匹配的节点的子集,但根据XSLT规范,它们都具有相同的优先级。因此,如果您希望第一个优先考虑,请给出明确的优先级,例如
<xsl:template match="escenic:escenic/escenic:content
[not(@exported-dbid=$allowedArticles)]" priority="6"/>
<xsl:template match="escenic:escenic/escenic:content" priority="5">
或者我怀疑父元素限定符只是噪声,因此您可以将规则写为:
<xsl:template match="escenic:content
[not(@exported-dbid=$allowedArticles)]" />
<xsl:template match="escenic:content">
如果您这样做,系统会计算出正确反映选择性的默认优先级,因此您无需添加手动优先级。
当然,按照@helderadocha的建议使规则互相排斥是另一种可能性,但一般来说XSLT难以实现,因此理解和使用模板规则优先级非常重要。