我有一个类似于此的XML文档:
<pipeline>
<log>
<error stageName="One" message="Ack!" />
<error stageName="Two" message="Ack!" />
<error stageName="Three" message="Ack!" />
</log>
<stages>
<stage name="One" />
<stage name="Two" />
</stages>
</pipeline>
我尝试使用XSLT报告按阶段分组的所有错误。在报告的最后,我希望所有与任何阶段无关的错误。我能够报告每个阶段的错误。现在我需要一种方法来有条件地显示所有其他错误。
这是我最接近的:
<xsl:template match="/pipeline">
<xsl:variable name="unknown.stages"
select="log/error[@stageName != stages/stage/@name]" />
<xsl:if test="count($unknown.stages) > 0">
<h1>Other Errors</h1>
<xsl:apply-templates select="$unknown.stages" />
</xsl:if>
</xsl:template>
但它最终会显示所有错误,而不仅仅是与舞台无关的错误。是否存在我可以在xsl:variable
声明中使用的XPath查询,以选择error
属性具有stageName
列表中不存在的值的所有stages/stage
个节点元素?
更新:这是正确的XPath查询。我必须在舞台元素上创建一个键,然后使用该键找到不匹配的错误:
<xsl:key name="stageName" match="/pipeline/stages/stage" use="@name" />
<xsl:template match="/pipeline">
<xsl:variable name="unknown.stages"
select="log/error[not(key('stageName',@stageName)]" />
<xsl:if test="count($unknown.stages) > 0">
<h1>Other Errors</h1>
<xsl:apply-templates select="$unknown.stages" />
</xsl:if>
</xsl:template>
答案 0 :(得分:1)
您确定要显示所有错误吗?使用当前的xpath,它将查找阶段元素,该元素是您选择的当前错误元素的子元素。我原以为表达式看起来更像是
<xsl:variable name="unknown.stages" select="log/error[@stageName != //stages/stage/@name]" />
话虽如此,这会返回所有错误元素,因为它返回错误元素,其中存在具有不同名称的阶段。
无论如何,要解决此问题,请考虑使用密钥查找阶段元素
<xsl:key name="stages" match="stage" use="@name" />
然后你可以像这样编写你的表达式,它应该根据你的要求检查是否存在:
<xsl:variable name="unknown.stages"select="log/error[not(key('stages', @stageName))]" />