我的XML代码& XSLT代码 解释: 我试图用
从元素中移动字符串'2'(tr[@type='detail'] and td[@column='1'])
到类别标题
(tr [@type='categoryhead' and level='2'])
非常感谢任何帮助 万分感谢
<!--=============My XML=============-->
<tbody xmlns="http://mynamespace.com">
<tr layoutcode="" type="categoryhead" level="1" categorykey="2789" hierarchykey="4921">
<td colname="1">Bonds</td>
</tr>
<tr layoutcode="" type="categoryhead" level="2" categorykey="3255" hierarchykey="4922">
<td colname="1">Beverages</td>
</tr>
<tr layoutcode="" type="detail" level="3" securitymasterkey="41164">
<td colname="1">Security_1(1,2)</td>
<td colname="2">500</td>`enter code here`
<td colname="3">330</td>
</tr>
<tr layoutcode="" type="detail" level="3" securitymasterkey="41167">
<td colname="1">Security_4(1,2,3,4)</td>
<td colname="2">10</td>
<td colname="3">265</td>
</tr>
<tr layoutcode="" type="categorytotal" level="2" categorykey="3255" hierarchykey="4922">
<td colname="1">Beverages</td>
<td colname="2">530</td>
<td colname="3">1,045</td>
</tr>
<tr layoutcode="" type="categorytotal" level="1" categorykey="2789" hierarchykey="4921">
<td colname="1">TOTAL Bonds</td>
<td colname="2">530</td>
<td colname="3">1,045</td>
</tr>
<tr layoutcode="" type="categoryhead" level="1" categorykey="2936" hierarchykey="4921">
<td colname="1">Options</td>
</tr>
<tr layoutcode="" type="categoryhead" level="2" categorykey="3248" hierarchykey="4922">
<td colname="1">Agriculture</td>
</tr>
<tr layoutcode="" type="detail" level="3" securitymasterkey="41168">
<td colname="1">Security_5(@,1)</td>
<td colname="2">10</td>
<td colname="3">890</td>
</tr>
<tr layoutcode="" type="detail" level="3" securitymasterkey="41168">
<td colname="1">Security_5(@,2)</td>
<td colname="2">10</td>
<td colname="3">890</td>
</tr>
<tr layoutcode="" type="categorytotal" level="2" categorykey="3248" hierarchykey="4922">
<td colname="1">Agriculture</td>
<td colname="2">10</td>
<td colname="3">890</td>
</tr>
</tbody>
XSLT,我试图将带有(tr [@ type ='detail']和td [@ column ='1'])的元素中的字符串'2'移动到类别标题(tr [@type ='categoryhead'和level ='2'])
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:a="http://mynamespace.com" version="2.0">
<!-- Global Variable -->
<xsl:variable name="arg1" select="'2'"></xsl:variable>
<!-- This identity template copies the document -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @* "/>
</xsl:copy>
</xsl:template>
<xsl:template match="a:tbody/a:tr[@type='categoryhead' and @level='2']/a:td">
<xsl:for-each select="//a:tbody/a:tr[@type='detail']/a:td[@colname='1'][contains(.,$arg1)]">
<xsl:variable name="IsFooted" select="contains(.,$arg1)"></xsl:variable>
<xsl:value-of select="count(//a:tbody/a:tr[@type='detail']/a:td[@colname='1'][contains(.,$arg1)])"/>
<xsl:choose>
<xsl:when test="$IsFooted='true'">
<xsl:value-of select="."/>
<xsl:value-of select="concat('(',concat($arg1,')'))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
所需的XML输出:
<tbody xmlns="http://mynamespace.com">
<tr layoutcode="" type="categoryhead" level="1" categorykey="2789" hierarchykey="4921">
<td colname="1">Bonds</td>
</tr>
<tr layoutcode="" type="categoryhead" level="2" categorykey="3255" hierarchykey="4922">
<td colname="1">Beverages (2)</td>
</tr>
<tr layoutcode="" type="detail" level="3" securitymasterkey="41164">
<td colname="1">Security_1(1)</td>
<td colname="2">500</td>
<td colname="3">330</td>
</tr>
<tr layoutcode="" type="detail" level="3" securitymasterkey="41167">
<td colname="1">Security_4(1,3,4)</td>
<td colname="2">10</td>
<td colname="3">265</td>
</tr>
<tr layoutcode="" type="categorytotal" level="2" categorykey="3255" hierarchykey="4922">
<td colname="1">Beverages</td>
<td colname="2">530</td>
<td colname="3">1,045</td>
</tr>
<tr layoutcode="" type="categorytotal" level="1" categorykey="2789" hierarchykey="4921">
<td colname="1">TOTAL Bonds</td>
<td colname="2">530</td>
<td colname="3">1,045</td>
</tr>
<tr layoutcode="" type="categoryhead" level="1" categorykey="2936" hierarchykey="4921">
<td colname="1">Options</td>
</tr>
<tr layoutcode="" type="categoryhead" level="2" categorykey="3248" hierarchykey="4922">
<td colname="1">Agriculture</td>
</tr>
<tr layoutcode="" type="detail" level="3" securitymasterkey="41168">
<td colname="1">Security_5(@,1)</td>
<td colname="2">10</td>
<td colname="3">890</td>
</tr>
<tr layoutcode="" type="detail" level="3" securitymasterkey="41168">
<td colname="1">Security_5(@,2)</td>
<td colname="2">10</td>
<td colname="3">890</td>
</tr>
<tr layoutcode="" type="categorytotal" level="2" categorykey="3248" hierarchykey="4922">
<td colname="1">Agriculture</td>
<td colname="2">10</td>
<td colname="3">890</td>
</tr>
</tbody>
答案 0 :(得分:0)
这里的术语不太清楚,因为在查看输出样本时,所发生的一切都是“(2)”被附加到特定的表格单元格,所以它并没有真正移动任何东西。
此外,您的问题标题提到了关于子元素的问题,但是看看XML结构,“细节”行实际上是“categoryhead”行的兄弟。这可能是问题所在;如何将“细节”行与关联的“categoryheader”关联起来。一种方法是使用密钥
<xsl:key name="row"
match="a:tr[@level != '1']"
use="generate-id(preceding-sibling::a:tr[@level=current()/@level - 1][1])" />
这将获取行(除了在级别1之外)并使用lowel @level属性将它们分组到前一行。
现在,对于你的模板匹配,因为你正在改变“td”元素,我会改变模板以匹配这样的元素,而不是“tr”元素
<xsl:template match="a:tbody/a:tr[@type='categoryhead' and @level='2']/a:td[@colname='1']">
然后您可以使用该键来获取“子”元素,但不考虑所有子元素是否包含'2',而是反转逻辑并检查是否有任何子元素不包含'2' “
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:a="http://composition.bowne.com/2010/v4" version="1.0">
<!-- Global Variable -->
<xsl:variable name="arg1" select="'2'"></xsl:variable>
<xsl:key name="row" match="a:tr[@level != '1']" use="generate-id(preceding-sibling::a:tr[@level=current()/@level - 1][1])" />
<!-- This identity template copies the document -->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a:tbody/a:tr[@type='categoryhead' and @level='2']/a:td[@colname='1']">
<xsl:variable name="IsMissing" select="key('row', generate-id(..))/a:td[@colname='1'][not(contains(text(), $arg1))]" />
<xsl:choose>
<xsl:when test="not($IsMissing)">
<xsl:value-of select="."/>
<xsl:value-of select="concat('(',concat($arg1,')'))"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
另外,XSLT中的命名空间与XML中的命名空间不匹配。你需要这些来匹配这个,但我认为这是一个错字。
编辑:要从“详细信息”行中删除“2”,请尝试添加以下模板。 'isMissing'变量有点混乱,因为它必须首先找到相关的'categoryhead'。另请注意,它使用“替换”,仅在XSLT 2.0中可用。
<xsl:template match="a:tbody/a:tr[@type='detail']/a:td[@colname='1']">
<xsl:variable name="parentLevel" select="../@level - 1" />
<xsl:variable name="IsMissing" select="key('row', generate-id(../preceding-sibling::a:tr[@level=$parentLevel][1]))/a:td[@colname='1'][not(contains(text(), $arg1))]" />
<xsl:choose>
<xsl:when test="not($IsMissing)">
<xsl:value-of select="replace(., concat(',', $arg1), '')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>