2

我有这样的xml:

  <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 中有 2 个变量:

  <xsl:variable name="only_need" select="/ROWSET/ROW[./FLD2='N2']"/>
  <xsl:variable name="only_need2" select="$only_need/FLD1[not(.=following::FLD1)]"/>

在名为“only_need”的变量中,我收到带有 S_Val IN (1, 2, 3) 的记录。但在名为“only_need2”的变量中,我只收到 FLD1 = P3。为什么第二个变量只接收 FLD1 = P3 的问题?

4

2 回答 2

1

only_need2包含其值与整个文档中所有后续元素的值不同FLD1的那些行的子代,而不仅仅是在. 所以你没有得到,因为稍后会有另一个(在第五行)。only_needFLD1only_needP2P2

如果您想要的实际上是每个不同only_needFLD1的最后一行,您可以使用键来执行此操作

<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()] )]" />

我在这里所做的是定义一个键,它将从行中提取所有元素FLD1,并按它们的值对它们进行分组。变量声明中的谓词使用此键仅选择每个组中的最后一个元素。FLD2N2FLD1

于 2012-09-28T09:01:29.660 回答
0

这回答了您从评论到 Ian Roberts 的好答案的问题:

你能告诉我,我怎样才能将“关注”仅用于“only_need”

事实上,这是一个纯粹的 XPath 问题。

可以避免使用键,而只使用诸如“前”或“后”之类的轴来查找“不同”元素,但是请记住,这非常慢 - O(N^2) 与使用相同键-(O(N)):

 <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>

当此转换应用于提供的 XML 文档时

<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>

计算 Xpath 表达式,并将如此定义的变量的内容$vOnlyNeedDistinct复制到输出

<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>
于 2012-09-28T12:48:45.917 回答