我对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"><1>Common stocks [Replacement]</td> (b)
<td colname="2"/>
</tr>
<tr layoutcode="" type="categoryhead" level="3" itemtype="categoryhead">
<td colname="1"><2>Health care&lt;softreturn&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“获取文本。我知道这听起来相当混乱,我知道我很遗憾尝试这是非常可怜的,但我非常感谢任何建议。
非常感谢 亚历克斯。
答案 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
。