2011-11-21 42 views
-1

我试图打印基于最后一个节点的条件行。 这是一个XML示例:XSL:从前一个节点访问数据

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

至极是正确的,但I'de喜欢删除“冗余”线,看起来像这样

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

我真的很难理解你的问题。谨慎地阐述并提供**最小有效** .xml/.xsl而不是件? – FailedDev

+0

你是对的,试图清理代码并结束清理太多 – vitohxc

回答

0

看起来你需要通过三维点元素循环,但是从元素信息在它们之前,只有在相关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 

请注意我正在使用一个键来查找关联的double元素为point3d。 XSLT的作用是每point3d元素,它匹配关联的double,但如果前一个double元素的值相同,则该元素将不输出任何内容。

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

+0

只是为了确定。在你的方法中,它是有效的,因为只有一个双重的,对吗? – vitohxc

+0

是的,因为在原始xml中每个点只有一个双精度值 –

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 
0

发帖时,我试图清理代码,但最终清理得太多。 point3d元素不是父母和孩子。他们处于相同的“水平”。

正确的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], .... 

我想现在很清楚,它的工作原理!

再一次,对不起,导致你错误。 并感谢您的快速解答。