在XSLT中使用模板创建属性的条件语句

时间:2013-08-14 11:02:53

标签: xml xslt grouping xslt-1.0 conditional-statements

如何获取属性的值并在条件语句中使用它。例如,我有<O Option="a" LineNr="1">,这是元素是另一个父元素下的子元素,它与其他元素组合在一起。所以我想要的条件是:if [value-of Option为null]然后[什么也不做] else-if [if检查下一个具有相同值的父元素下元素属性的值是否为空]。如果有3个父元素包含带有Option属性的元素,并且所有属性都不为空 - 那么将它们分组。 我已完成分组,但它与我现在想要使用的此属性无关。所以我只需要制定条件陈述。

编辑:提供输入和输出所需的示例 输入示例1:

<Area>
     <Type>A</Type>
     <Street>
       <Position>5</Position>
       <House>
       <L Option="" LineNr="1">
       --> some elements
       </L>
       </House>
     </Street>
     <Street>
       <Position>5</Position>
       <Block>
       <O Option="" LineNr="1">
       --> some elements
       </O>
       </Block>
     </Street>
     <Street>
       <Position>6</Position>
       <House>
       <L Option="o" LineNr="1">
       --> some elements
       </L>
       </House>
     </Street>
     <Street>
       <Position>6</Position>
       <Block>
       <O Option="" LineNr="1">
       --> some elements
       </O>
       </Block>
     </Street>
   </Area>

期望的输出:

<Area>
   <Type>A</Type>
     <Street>
       <Position>5</Position>
       <House>
       <L Option="" LineNr="1">
       --> some elements
       </L>
       </House>
       <Block>
       <O Option="" LineNr="1">
       --> some elements
       </O>
       </Block>
     </Street>
     <Street>
       <Position>6</Position>
       <House>
       <L Option="o" LineNr="1">
       --> some elements
       </L>
       </House>
       <Block>
       <O Option="" LineNr="1">
       --> some elements
       </O>
       </Block>
     </Street>
   </Area>

但是如果在相同的位置编号中,所有出现在L或O的Option属性中都有一个值,那么我希望它们排列在另一个位置编号的下面。像那样:

输入示例2:

       <Area>
         <Type>A</Type>
         <Street>
           <Position>5</Position>
           <House>
           <L Option="" LineNr="1">
           --> some elements
           </L>
           </House>
         </Street>
         <Street>
           <Position>5</Position>
           <Block>
           <O Option="" LineNr="1">
           --> some elements
           </O>
           </Block>
         </Street>
         <Street>
           <Position>6</Position>
           <House>
           <L Option="o" LineNr="1">
           --> some elements
           </L>
           </House>
         </Street>
         <Street>
           <Position>6</Position>
           <Block>
           <O Option="a" LineNr="1">
           --> some elements
           </O>
           </Block>
         </Street>
       </Area>

然后输出将是:

     <Area>
       <Type>A</Type>
         <Street>
           <Position>5</Position>
           <House>
           <L Option="" LineNr="1">
           --> some elements
           </L>
           </House>
           <Block>
           <O Option="" LineNr="1">
           --> some elements
           </O>
           </Block>

           <House>
           <L Option="o" LineNr="1">
           --> some elements
           </L>
           </House>
           <Block>
           <O Option="a" LineNr="1">
           --> some elements
           </O>
           </Block>
         </Street>
       </Area>

因为现在位置6已经消失并且其子元素被分组在上面的出现位置(在这种情况下为5,在同一类型中),因为所有属性L或O元素中的选项具有值(可以是要么&#34; a&#34;或&#34; o&#34;,如果相关的话。)

这是我现在使用的XSLT。它只将相同位置编号的不同出现的元素分组在一个数字下:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:strip-space elements="*" />
  <xsl:output method="xml" indent="yes" />

  <xsl:key name="streetByPosition" match="Street" use="concat(../Type, '|', Position)" />

  <xsl:template match="@*|node()">
    <xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy>
  </xsl:template>

  <!-- for the first Street in each Position -->
  <xsl:template match="Street[generate-id() =
                            generate-id(key('streetByPosition', concat(../Type, '|', Position))[1])]">
    <Street>
      <!-- copy in the Position element once only -->
      <xsl:apply-templates select="Position" />
      <!-- copy in all sub-elements except Position from all matching Streets-->
      <xsl:apply-templates select="
            key('streetByPosition', concat(../Type, '|', Position))/*[not(self::Position)]" />
    </Street>
  </xsl:template>

  <!-- ignore all other Street elements -->
  <xsl:template match="Street" />
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:0)

要通过排序获得所需结果,您可以对节点进行分组,例如:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<Area>
    <Type>A</Type>  
  <xsl:for-each select="/Area/Street">  

    <xsl:sort select="Position"> </xsl:sort>  

      <xsl:sort select="node()[name(.)!='Position']"> </xsl:sort>

     <xsl:sort select="node()[name(.)!='Position']/node()/@Option"> </xsl:sort>      

    <xsl:copy-of select="." />
  </xsl:for-each>  
  </Area>
</xsl:template>
</xsl:stylesheet>