Xslt xsl“following”返回的不是预期的结果
我有这样的xml:Xslt xsl“following”返回的不是预期的结果,xslt,xpath,Xslt,Xpath,我有这样的xml: <ROWSET> <ROW> <FLD1>P2</FLD1> <S_VAL>1</S_VAL> <FLD2>N2</FLD2> </ROW> <ROW> <FLD1>P3</FLD1> <S_VAL>2</S_VAL>
<ROWSET>
<ROW>
<FLD1>P2</FLD1>
<S_VAL>1</S_VAL>
<FLD2>N2</FLD2>
</ROW>
<ROW>
<FLD1>P3</FLD1>
<S_VAL>2</S_VAL>
<FLD2>N2</FLD2>
</ROW>
<ROW>
<FLD1>P3</FLD1>
<S_VAL>3</S_VAL>
<FLD2>N2</FLD2>
</ROW>
<ROW>
<FLD1>P4</FLD1>
<S_VAL>4</S_VAL>
<FLD2>N3</FLD2>
</ROW>
<ROW>
<FLD1>P2</FLD1>
<S_VAL>5</S_VAL>
<FLD2>N3</FLD2>
</ROW>
</ROWSET>
我的xsl中有两个变量:
<xsl:variable name="only_need" select="/ROWSET/ROW[./FLD2='N2']"/>
<xsl:variable name="only_need2" select="$only_need/FLD1[not(.=following::FLD1)]"/>
在名为only的变量中,我需要接收1、2、3中带有S_Val的记录。
但在名为_need2的变量中,我只收到FLD1=P3。
为什么第二个变量receve only FLD1=P3?only_need2包含only_need中那些行的FLD1子行,这些行的值不同于整个文档中所有后续FLD1元素的值,而不仅仅是only_need2。所以你没有得到P2,因为第五排后面还有一个P2
如果您想要的实际上是每个不同FLD1值所需的最后一行,那么可以使用一个键
<xsl:key name="key_only_need2" match="/ROWSET/ROW[FLD2='N2']/FLD1" use="." />
<xsl:variable name="only_need2" select="$only_need/FLD1[
generate-id() = generate-id( key('key_only_need2', .)[last()] )]" />
我在这里所做的是定义一个键,它将从FLD2为N2的行中提取所有FLD1元素,并根据它们的FLD1值对它们进行分组。变量声明中的谓词使用此键仅从每个组中选择最后一个元素。这回答了您对Ian Roberts的正确答案的评论中的问题: 你能告诉我,我怎样才能只为你的需要使用下面的内容 事实上,这是一个纯粹的XPath问题 在查找不同的元素时,可以避免使用键,而只使用轴(如前面或后面),但是请记住,与使用键相比,^2上的速度非常慢:
谢谢你能告诉我,我怎样才能只为你的需要而使用下面的内容呢。感谢您的详细回答。只有10-15条记录将以$vOnlyNeed为单位。一切都像你一样。但并不完全清楚过滤器是如何工作的`[count.|$vOnlyNeed=count$vOnlyNeed]`诀窍是XPath在节点集上工作,因此当您使用exprA构建联合时,两个表达式匹配的exprB节点只计数一次。因此,[count.|$vOnlyNeed=count$vOnlyNeed]当且仅当所讨论的节点为真时才为真。是集合$vOnlyNeed的成员。
<xsl:variable name="vOnlyNeed" select="/*/*[FLD2='N2']"/>
<xsl:variable name="vOnlyNeedDistinct" select=
"$vOnlyNeed
[not(FLD1
=
following::*
[count(.|$vOnlyNeed) = count($vOnlyNeed)]
/FLD1)]
"/>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vOnlyNeed" select="/*/*[FLD2='N2']"/>
<xsl:variable name="vOnlyNeedDistinct" select=
"$vOnlyNeed
[not(FLD1
=
following::*
[count(.|$vOnlyNeed) = count($vOnlyNeed)]
/FLD1)]
"/>
<xsl:template match="/">
<xsl:copy-of select="$vOnlyNeedDistinct"/>
</xsl:template>
</xsl:stylesheet>
<ROWSET>
<ROW>
<FLD1>P2</FLD1>
<S_VAL>1</S_VAL>
<FLD2>N2</FLD2>
</ROW>
<ROW>
<FLD1>P3</FLD1>
<S_VAL>2</S_VAL>
<FLD2>N2</FLD2>
</ROW>
<ROW>
<FLD1>P3</FLD1>
<S_VAL>3</S_VAL>
<FLD2>N2</FLD2>
</ROW>
<ROW>
<FLD1>P4</FLD1>
<S_VAL>4</S_VAL>
<FLD2>N3</FLD2>
</ROW>
<ROW>
<FLD1>P2</FLD1>
<S_VAL>5</S_VAL>
<FLD2>N3</FLD2>
</ROW>
</ROWSET>
<ROW>
<FLD1>P2</FLD1>
<S_VAL>1</S_VAL>
<FLD2>N2</FLD2>
</ROW>
<ROW>
<FLD1>P3</FLD1>
<S_VAL>3</S_VAL>
<FLD2>N2</FLD2>
</ROW>