XSL:访问上一节点的数据

时间:2011-11-21 17:56:52

标签: xml xslt

我正在尝试根据最后一个节点打印条件行。 这是一个xml示例:

 <point3d name="pts_p" index="0" x="-119.880476" y="2.012081" z="186.208920"/>
<double name="pts_tool" index="0">100.000000</double>

<point3d name="pts_p" index="1" x="-119.359576" y="-4.849939" z="186.220865"/>
<double name="pts_tool" index="1">100.000000</double>

<point3d name="pts_p" index="2" x="-117.434589" y="-11.072205" z="186.219202"/>
<double name="pts_tool" index="2">0.000000</double>

<point3d name="pts_p" index="3" x="-113.846437" y="-17.133645" z="185.787516"/>
<double name="pts_tool" index="3">100.000000</double>

<point3d name="pts_p" index="4" x="-107.697823" y="-22.645023" z="185.765083"/>
<double name="pts_tool" index="4">100.000000</double>

并使用此xsl(示例):

<xsl:if test="$toolpoint[@index = $i] = 0">
   <xsl:text>    SetDo RoughMotorOn, 0;&#xA;</xsl:text>
</xsl:if>    
<xsl:if test="$toolpoint[@index = $i] = 100">
   <xsl:text>    SetDo RoughMotorOn, 1;&#xA;</xsl:text>
</xsl:if>

给我输出:

SetDo RoughMotorOn, 1;
MoveL [[-119.880476,....
SetDo RoughMotorOn, 1;
MoveL [[-119.359576,....
SetDo RoughMotorOn, 0;
MoveL [[-117.434589,....
SetDo RoughMotorOn, 1;
MoveL [[-113.846437,....
SetDo RoughMotorOn, 1;
MoveL [[-107.697823, ....

这是正确的,但我想删除“冗余”行,看起来像这样

SetDo RoughMotorOn, 1;
MoveL [[-119.880476,....
MoveL [[-119.359576,....
SetDo RoughMotorOn, 0;
MoveL [[-117.434589,....
SetDo RoughMotorOn, 1;
MoveL [[-113.846437,....
MoveL [[-107.697823,....

有什么方法可以做到这一点吗?

在我上次尝试时,我使用了这个xsl代码:

<xsl:choose>
<xsl:when test="position()=1">
  <xsl:if test="$toolpoint[@index = $i] = 0">
     <xsl:text>    SetDo RoughMotorOn, 0;&#xA;</xsl:text>
  </xsl:if>  
  <xsl:if test="$toolpoint[@index = $i] = 100">
     <xsl:text>    SetDo RoughMotorOn, 1;&#xA;</xsl:text>
  </xsl:if>     
</xsl:when>
<xsl:otherwise>
  <xsl:if test="$toolpoint[@index = $i] = $toolpoint[@index != $i-1]">
     <xsl:if test="$toolpoint[@index = $i] = 0">
        <xsl:text>    SetDo RoughMotorOn, 0;&#xA;</xsl:text>
     </xsl:if>   
     <xsl:if test="$toolpoint[@index = $i] = 100">
        <xsl:text>    SetDo RoughMotorOn, 1;&#xA;</xsl:text>
     </xsl:if>      
  </xsl:if>
</xsl:otherwise>
</xsl:choose>

3 个答案:

答案 0 :(得分:1)

此转化

<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:template match="point3d">
   <xsl:apply-templates mode="control"
    select="following-sibling::double[1]"/>
   <xsl:value-of select="concat(' MoveL [[', @x, '&#xA;')"/>
 </xsl:template>

 <xsl:template match="double" mode="control">
  <xsl:text>                         </xsl:text>
 </xsl:template>
 <xsl:template mode="control" match=
    "double[not(. = preceding-sibling::double[1])]">
    SetDo RoughMotorOn, <xsl:value-of select="substring(.,1,1)"/>
 </xsl:template>
 <xsl:template match="text()"/>
 <xsl:template match="text()" mode="control"/>
</xsl:stylesheet>

应用于提供的输入(制作格式良好的XML文档):

<t>
    <point3d name="pts_p" index="0" x="-119.880476" y="2.012081" z="186.208920"/>
    <double name="pts_tool" index="0">100.000000</double>
    <point3d name="pts_p" index="1" x="-119.359576" y="-4.849939" z="186.220865"/>
    <double name="pts_tool" index="1">100.000000</double>
    <point3d name="pts_p" index="2" x="-117.434589" y="-11.072205" z="186.219202"/>
    <double name="pts_tool" index="2">0.000000</double>
    <point3d name="pts_p" index="3" x="-113.846437" y="-17.133645" z="185.787516"/>
    <double name="pts_tool" index="3">100.000000</double>
    <point3d name="pts_p" index="4" x="-107.697823" y="-22.645023" z="185.765083"/>
    <double name="pts_tool" index="4">100.000000</double>
</t>

生成想要的正确结果

SetDo RoughMotorOn, 1 MoveL [[-119.880476
                      MoveL [[-119.359576

SetDo RoughMotorOn, 0 MoveL [[-117.434589

SetDo RoughMotorOn, 1 MoveL [[-113.846437
                      MoveL [[-107.697823

答案 1 :(得分:0)

看起来您需要遍历 point3d 元素,但只有在关联的 double 时,才会在 double 元素中添加信息。元素与前一元素的价值不同。

作为一个起点,为了帮助您以不同的方式思考您的问题,请尝试使用此XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="double" match="double" use="@index"/>

    <xsl:template match="/tools">
        <xsl:apply-templates select="point3d"/>
    </xsl:template>

    <xsl:template match="point3d">
        <xsl:apply-templates select="key('double', @index)"/>
            <xsl:text>MoveL [[</xsl:text><xsl:value-of select="@x" /><xsl:text>&#13;</xsl:text>
        </xsl:template>

    <xsl:template match="double[. = 0]">
        <xsl:text>SetDo RoughMotorOn, 0;&#13;</xsl:text>
    </xsl:template>

    <xsl:template match="double[. = 100]">
        <xsl:text>SetDo RoughMotorOn, 1;&#13;</xsl:text>
    </xsl:template>

    <xsl:template match="double[. = preceding-sibling::double[1]/.]"/>
</xsl:stylesheet>

应用于以下XML

<tools>
<point3d name="pts_p" index="0" x="-119.880476" y="2.012081" z="186.208920"/>
<double name="pts_tool" index="0">100.000000</double>
<point3d name="pts_p" index="1" x="-119.359576" y="-4.849939" z="186.220865"/>
<double name="pts_tool" index="1">100.000000</double>
<point3d name="pts_p" index="2" x="-117.434589" y="-11.072205" z="186.219202"/>
<double name="pts_tool" index="2">0.000000</double>
<point3d name="pts_p" index="3" x="-113.846437" y="-17.133645" z="185.787516"/>
<double name="pts_tool" index="3">100.000000</double>
<point3d name="pts_p" index="4" x="-107.697823" y="-22.645023" z="185.765083"/>
<double name="pts_tool" index="4">100.000000</double>
</tools>

以下是输出

SetDo RoughMotorOn, 1;
MoveL [[-119.880476
MoveL [[-119.359576
SetDo RoughMotorOn, 0;
MoveL [[-117.434589
SetDo RoughMotorOn, 1;
MoveL [[-113.846437
MoveL [[-107.697823

请注意我使用密钥查找 point3d 的关联 double 元素。 XSLT对每个 point3d 元素的作用是什么,它匹配关联的 double ,但如果前一个 double 元素是一样的。

请注意与 double 元素匹配的模板的顺序非常重要。忽略具有相同先前值的元素的那个必须是最后一个。

答案 2 :(得分:0)

发布问题时,我试图清理代码,但结束了清理过多。 point3d 元素不是父元素, double 元素。他们处于同一“水平”。

正确的xml。

<object id="4" class="Polyline7D">
   <int name="type">0</int>
   <int name="npts">7</int>
   <int name="n_passes">1</int>
   <double name="power">0.000000</double>
   <double name="width">0.000000</double>
   <int name="polside">0</int>
   <point3d name="pts_p" index="0" x="-119.880476" y="2.012081" z="186.208920"/>
   <double name="pts_e_roll" index="0">-179.999761</double>
   <double name="pts_e_pitch" index="0">-87.567468</double>
   <double name="pts_e_yaw" index="0">9.954604</double>
   <double name="pts_tool" index="0">100.000000</double>
   <double name="pts_velocity" index="0">100.000000</double>
   <point3d name="pts_p" index="1" x="-119.359576" y="-4.849939" z="186.220865"/>
   <double name="pts_e_roll" index="1">-179.998973</double>
   <double name="pts_e_pitch" index="1">-87.416108</double>
   <double name="pts_e_yaw" index="1">14.283145</double>
   <double name="pts_tool" index="1">100.000000</double>
   <double name="pts_velocity" index="1">30.000000</double>
   <point3d name="pts_p" index="2" x="-117.434589" y="-11.072205" z="186.219202"/>
   <double name="pts_e_roll" index="2">-179.998973</double>
   <double name="pts_e_pitch" index="2">-85.716906</double>
   <double name="pts_e_yaw" index="2">22.475456</double>
   <double name="pts_tool" index="2">100.000000</double>
   <double name="pts_velocity" index="2">40.000000</double>
   <point3d name="pts_p" index="3" x="-113.846437" y="-17.133645" z="185.787516"/>
   <double name="pts_e_roll" index="3">179.999352</double>
   <double name="pts_e_pitch" index="3">-82.368383</double>
   <double name="pts_e_yaw" index="3">35.771100</double>
   <double name="pts_tool" index="3">0.000000</double>
   <double name="pts_velocity" index="3">50.000000</double>
   <point3d name="pts_p" index="4" x="-107.697823" y="-22.645023" z="185.765083"/>
   <double name="pts_e_roll" index="4">-179.999933</double>
   <double name="pts_e_pitch" index="4">-77.401336</double>
   <double name="pts_e_yaw" index="4">48.719782</double>
   <double name="pts_tool" index="4">0.000000</double>
   <double name="pts_velocity" index="4">60.000000</double>
   <point3d name="pts_p" index="5" x="-102.213016" y="-25.649298" z="185.527503"/>
   <double name="pts_e_roll" index="5">-179.999933</double>
   <double name="pts_e_pitch" index="5">-70.869095</double>
   <double name="pts_e_yaw" index="5">60.187768</double>
   <double name="pts_tool" index="5">0.000000</double>
   <double name="pts_velocity" index="5">70.000000</double>
   <point3d name="pts_p" index="6" x="-95.371503" y="-27.801876" z="185.264439"/>
   <double name="pts_e_roll" index="6">-179.999933</double>
   <double name="pts_e_pitch" index="6">-58.863558</double>
   <double name="pts_e_yaw" index="6">70.870345</double>
   <double name="pts_tool" index="6">100.000000</double>
   <double name="pts_velocity" index="6">80.000000</double>
</object>

点的唯一标志是index =#。 所以我误导了你(抱歉可能有错) 但我根据索引

管理了一个解决方案

xsl上的模板:

<xsl:template match="object[@class='Polyline7D']">
   <xsl:variable name="type" select="int[@name='type']"/>
   <xsl:variable name="power" select="double[@name='power']"/>
   <xsl:variable name="npasses" select="int[@name='n_passes']"/>
   <xsl:variable name="width" select="double[@name='width']"/>
   <xsl:variable name="velocity" select="double[@name='pts_velocity']"/>
   <xsl:variable name="toolpoint" select="double[@name='pts_tool']"/>

   <xsl:for-each select="point3d[@name='pts_p']">
     <xsl:variable name="i" select="@index"/>
     <xsl:variable name="a" select="@index - 1"/>

     <xsl:if test="$i = 0">
       <xsl:if test="$toolpoint[@index = $i] = 0">
         <xsl:text>    SetDo RoughMotorOn, 0;&#xA;</xsl:text>
       </xsl:if>     
       <xsl:if test="$toolpoint[@index = $i] = 100">
         <xsl:text>    SetDo RoughMotorOn, 1;&#xA;</xsl:text>
       </xsl:if>        
     </xsl:if>

     <xsl:if test="$i != 0">
       <xsl:if test="$toolpoint[@index = $i] != $toolpoint[@index = $a]">
         <xsl:if test="$toolpoint[@index = $i] = 0">
           <xsl:text>    SetDo RoughMotorOn, 0;&#xA;</xsl:text>
         </xsl:if>   
         <xsl:if test="$toolpoint[@index = $i] = 100">
           <xsl:text>    SetDo RoughMotorOn, 1;&#xA;</xsl:text>
         </xsl:if>
       </xsl:if>        
     </xsl:if>

     <xsl:text>    MoveL [</xsl:text>
     <xsl:text>[</xsl:text>
     <xsl:value-of select="format-number(@x, '0.000000')"/>
     <xsl:text>,</xsl:text>
     <xsl:value-of select="format-number(@y, '0.000000')"/>
     <xsl:text>,</xsl:text>
     <xsl:value-of select="format-number(@z, '0.000000')"/>
     <xsl:text>],</xsl:text>

     <!-- More elements to complete "MoveL" line
          but irrelevant to question
     -->

   </xsl:for-each>
</xsl:template>

结果:

SetDo RoughMotorOn, 1;

MoveL [[-119.880476,2.012081,186.208920], ....

MoveL [[-119.359576,-4.849939,186.220865], ....

MoveL [[-117.434589,-11.072205,186.219202], ....

SetDo RoughMotorOn, 0;

MoveL [[-113.846437,-17.133645,185.787516], ....

MoveL [[-107.697823,-22.645023,185.765083], ....

MoveL [[-102.213016,-25.649298,185.527503], ....

SetDo RoughMotorOn, 1;

MoveL [[-95.371503,-27.801876,185.264439], ....

我认为现在很清楚它有效!

再一次,抱歉引起你的错误。 谢谢你的快速回答。