XSLT确定要选择的节点

时间:2017-10-25 20:42:51

标签: xml xslt

我有一个xml结构,如下所示:

<Person>
  <ID> 123 </ID>
  <Type> L </Type>
</Person>    
<Person>
  <ID> 456 </ID>
  <Type> N </Type>
</Person>    
<Person>
  <ID> 123 </ID>
  <Type> U </Type>
</Person>

人在重复,无限,但我只关心这些&#34;类型&#34;。我想以某种方式只选择基于类型,但优先考虑它,不知何故。

我需要在类型为L时始终选择ID,而不管其他是什么。如果L不在那里,选择N,如果N不在那里,则U.最后,如果U不在那里,则根本不输出节点。

我已经尝试过嵌套选择:(如果这在语法上不正确,我道歉,我手动输入以消除复杂性。

<xsl:choose>
  <xsl:when test = "Person/Type='L'>
    <L-ID>
      <xsl:value-of "Person[Type = 'L']/ID" />
    </L-ID>
  </xsl:when>
  <xsl:otherwise>
      <xsl:when test = "Person/Type='N'>
        <N-ID>
          <xsl:value-of "Person[Type = 'N']/ID" />
        </N-ID>
      </xsl:when>
      <xsl:otherwise>
          <xsl:when test = "Person/Type='U'>
            <U-ID>
              <xsl:value-of "Person[Type = 'U']/ID" />
            </U-ID>
          </xsl:when>
      </xsl:otherwise>
  </xsl:otherwise>
</xsl:choose>

我也想过可能会使用Ifs和Chooses的组合,但我不能完全围绕这三个条件。我已经尝试绘制真值表,并且无法让它做我想做的事。

如果有帮助,我想要的表是:

 U | L | N |   Output  | XML
---+---+---+-----------+
 1   1   1    L        | <L-ID> 123 </L-ID>
 1   1   0    L        | <L-ID> 123 </L-ID>
 1   0   1    N        | <N-ID> 456 </N-ID> 
 1   0   0    U        | <U-ID> 789 </U-ID> 
 0   1   1    L        | <L-ID> 123 </L-ID>
 0   1   0    L        | <L-ID> 123 </L-ID>
 0   0   1    N        | <N-ID> 456 </N-ID> 
 0   0   0    Nothing  |

1 个答案:

答案 0 :(得分:1)

xsl:choose的语法是这个......

    <xsl:choose>
      <xsl:when test="Person/Type=' L '">
        <L-ID>
          <xsl:value-of select="Person[Type = ' L ']/ID" />
        </L-ID>
      </xsl:when>
      <xsl:when test="Person/Type=' N '">
        <N-ID>
          <xsl:value-of select="Person[Type = ' N ']/ID" />
        </N-ID>
      </xsl:when>
      <xsl:when test="Person/Type=' U '">
        <U-ID>
          <xsl:value-of select="Person[Type = ' U ']/ID" />
        </U-ID>
      </xsl:when>
    </xsl:choose>
</xsl:template>

请注意在支票中使用空格,因为类型节点中的字母周围有空格; <Type> L </Type>。编写xsl:when测试的另一种方法是

      <xsl:when test="Person[normalize-space(Type)= 'L']">
        <L-ID>
          <xsl:value-of select="Person[normalize-space(Type)= 'L']/ID" />
        </L-ID>
      </xsl:when>

或者,你可以利用你想要选择的字母按字母顺序排列的事实,所以你也可以这样做..

<xsl:for-each select="Person[normalize-space(Type) = 'L' or normalize-space(Type) = 'N' or normalize-space(Type) = 'U']">
    <xsl:sort select="Type" />
    <xsl:if test="position() = 1">
        <xsl:element name="{normalize-space(Type)}-ID">
            <xsl:value-of select="ID" />
        </xsl:element>
    </xsl:if>
</xsl:for-each>

如果您可以使用XSLT 2.0,则可以将xsl:for-each简化为此...

<xsl:for-each select="Person[normalize-space(Type) = ('L', 'N', 'U')]">
相关问题