在XSLT 1.0转换期间首次出现与标准匹配的节点

时间:2017-04-19 18:08:04

标签: xml xslt xpath

我正在尝试获取第一次出现的Machine / Properties / Axes / Axis / AxisID / Name值,其中标准Machine / Properties / Axes / Axis / Type = Rotary,以便我可以使用Name填充Top元素元件。

我尝试了以下XSLT模板,但它没有产生正确的输出:

 <xsl:template match="cd:Machine/cd:Properties[cd:Axes/cd:Axis/cd:Type='Rotary'][1]/cd:Rotaries/cd:Top">
    <xsl:copy>
      <Axis>
        <xsl:value-of select="ancestor::cd:Properties/cd:Axes/cd:Axis/cd:AxisID/cd:Name" />
      </Axis>
      <IsIndexed>false</IsIndexed>
      <IsManual>false</IsManual>
    </xsl:copy>
  </xsl:template> 

Top元素的所需输出:

<Top>
   <Axis>R1</Axis>
   <IsIndexed>false</IsIndexed>
   <IsManual>false</IsManual>
</Top>

输入:

<?xml version="1.0" encoding="utf-8"?>
<ArrayOfMachine xmlns="http://schemas.datacontract.org/2004/07/CMachine" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Machine>
    <Price>120000</Price>
    <Properties>
      <Axes>
        <Axis>
          <AxisID>
            <Name>X</Name>
            <Type>X</Type>
          </AxisID>
          <Type>Linear</Type>
        </Axis>
        <Axis>
          <AxisID>
            <Name>Y</Name>
            <Type>Y</Type>
          </AxisID>
          <Type>Linear</Type>
        </Axis>
        <Axis>
          <AxisID>
            <Name>Z</Name>
            <Type>Z</Type>
          </AxisID>
          <Type>Linear</Type>
        </Axis>
        <Axis>
          <AxisID>
            <Name>R1</Name>
            <Type>B</Type>
          </AxisID>
          <Type>Rotary</Type>
        </Axis>
        <Axis>
          <AxisID>
            <Name>R2</Name>
            <Type>C</Type>
          </AxisID>
          <Type>Linear</Type>
        </Axis>
      </Axes>
      <Ordering>XR1YR2Z</Ordering>
      <Rotaries>
        <Top i:nil="true" />
        <Bottom i:nil="true"/>
        <IsIndexed>false</IsIndexed>
        <IsManual>false</IsManual>
        <Mode>222</Mode>
      </Rotaries>
    </Properties>
  </Machine>
</ArrayOfMachine>

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

[更新]

在使用libxslt 1.1.28的xsltproc进行测试时,我发现在匹配模式与位置谓词方面存在不一致的错误行为。此版本的xsltproc通过此匹配表达式将模板与示例中的某个节点匹配:

cd:Machine/cd:Properties[cd:Axes/cd:Axis/cd:Type = 'Rotary'][1]

,在该模板中,它通过表达式

选择一个非空节点集
cd:Rotaries/cd:Top

。以这种方式选择的节点也应该与表达式

的模板匹配
cd:Machine/cd:Properties[cd:Axes/cd:Axis/cd:Type='Rotary'][1]/cd:Rotaries/cd:Top

,但xsltproc实际上与输入到模板的任何节点都不匹配,其匹配表达式。这不一定与您的问题直接相关,但这是考虑您的方法变体的原因。

无论如何,select中的xsl:value-of表达式肯定是不正确的。它选择一个包含所有轴的<cd:Name>元素的节点集,而不仅仅是类型为'Rotary'的节点集,并将其转换为字符串会产生集合中的第一个节点。那不是你想要的那个。尽管我在上面描述了不一致,但我发现您的匹配表达式的变体对我来说是select xsl:value-of表达式,可以选择您想要的节点。把它放在一起,然后,这个模板对我来说就像你想要的那样:

<xsl:template match="cd:Machine/cd:Properties[cd:Axes/cd:Axis/cd:Type='Rotary']/cd:Rotaries/cd:Top">
    <xsl:copy>
      <Axis>
        <xsl:value-of select="ancestor::cd:Properties/cd:Axes/cd:Axis[cd:Type = 'Rotary'][1]/cd:AxisID/cd:Name" />
      </Axis>
      <IsIndexed>false</IsIndexed>
      <IsManual>false</IsManual>
    </xsl:copy>
  </xsl:template> 
</xsl:stylesheet>