如何使用xslt识别元素中的文本

时间:2014-04-09 12:48:07

标签: xml xslt xpath

我对XSLT / XPath有疑问。我对此有点新意,因此没有太多线索所以请原谅我,如果这听起来很愚蠢。这是我的XML文件的片段:

<section xmlns="http://composition.companyA.com/v4" name="SOI" code=""  type="Table"  style="">
 <table xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" cols="5">
    <colspec colnum="1" colname="1"/>
    <colspec colnum="2" colname="2"/>
    <tbody>
      <tr layoutcode="" type="categoryhead" level="2" itemtype="categoryhead">
        <td colname="1">&lt;1&gt;Common stocks [Replacement]</td>  (b)
        <td colname="2"/>
      </tr>
      <tr layoutcode="" type="categoryhead" level="3" itemtype="categoryhead">
        <td colname="1">&lt;2&gt;Health care&amp;lt;softreturn&amp;gt;21.27%</td>
        <td colname="2"/>
      </tr>
      <tr layoutcode="" type="detail" level="4" itemtype="detail">
        <td colname="1"/>
        <td colname="2">Nebworth Sciences [This Tag], Inc.[$1$]</td>  (a)
      </tr>
    </tbody>
  </table>
</section>

以及我的XSLT程序的摘录:

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

<xsl:template match="tr/td[contains(text(),'This Tag')]">
    <xsl:variable name="GrandParentReplacementTag" select="'Asset Type'"></xsl:variable>
    <xsl:variable name="lev" select="../@level"/>
    <xsl:call-template name="replace-this">
        <xsl:with-param name="text" select="."/>
        <xsl:with-param name="replace" select="$GrandParentReplacementTag" />
        <xsl:with-param name="by" select="../preceding-sibling::tr[@type = 'categoryhead' and @level = $lev - 2][1]/td[@colname = 'caption']/text()" />
    </xsl:call-template>
</xsl:template>

...我想做的是能够识别一个“td”节点,该节点的文本包含“This Tag”,然后转到第一个前面的“tr”节点,其“type”属性为“ categoryhead“并在其文本中包含”Replacement“,然后从colname =”1“的子节点”td“获取文本。我知道这听起来相当混乱,我知道我很遗憾尝试这是非常可怜的,但我非常感谢任何建议。

非常感谢 亚历克斯。

1 个答案:

答案 0 :(得分:0)

问题在于您的整个<section>及其包含的所有内容都位于XML命名空间(xmlns="http://composition.companyA.com/v4")中。

它没有前缀,因此它是默认命名空间并传播到其中的所有元素。

因此,您必须在XPath表达式中使用该命名空间,否则他们不会选择任何内容。

在XSLT 1.0中无法使用XPath的默认命名空间,因此必须定义前缀 **

<xsl:stylesheet ... xmlns:v4="http://composition.companyA.com/v4">

...并在XPath表达式中使用前缀:

<xsl:template match="v4:td[contains(text(), 'This Tag')]">
    <xsl:call-template name="replace-this">
        <xsl:with-param name="text" select="." />
        <xsl:with-param name="replace" select="'Asset Type'" />
        <xsl:with-param name="by" select="
            ../preceding-sibling::v4:tr[
                @type = 'categoryhead'  
                and @level = current()/../@level - 2
                and contains(., 'Replacement')
            ][1]/v4:td[@colname = '1']/text()
        " />
    </xsl:call-template>
</xsl:template>

请注意使用current()功能。


** XSLT 2.0修复了这个问题,您可以在那里使用xpath-default-namespace