使用 XSLT 将一个元素的值添加到另一个元素
Use XSLT to add value from one element to another
我有一个源 XML 文件如下:
<section name="Test" code="" type="Table" fundid="15" subtype="SOI1" style="" xmlns="http://composition.bowne.com/2010/v4">
<table xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" accountperiod="2014-07-31" accountperiodtype="0" code="I2" name="Holdings" fundid="15" type="" cols="2">
<colspec colnum="1" colname="1" />
<colspec colnum="2" colname="2" />
<tbody>
<tr type="categoryhead" level="1" itemtype="categoryhead" categorykey="621" hierarchykey="989">
<td colname="1">
<datapoint type="Regular" subtype="" name="Caption" value="Health Care Equipment & Supplies" display="always">Health Care Equipment & Supplies</datapoint>
</td>
<td colname="2">
<datapoint type="Regular" subtype="" name="PercentOfNetAssets" value="16.6" display="always">16.6</datapoint>
</td>
</tr>
<tr type="categoryhead" level="1" itemtype="categoryhead" categorykey="623" hierarchykey="989">
<td colname="1">
<datapoint type="Literal" subtype="Custom" name="All Others*" value="All Others*" display="always">All Others*</datapoint>
</td>
<td colname="2">
<datapoint type="Regular" subtype="" name="PercentOfNetAssets" value="1.5" display="always">[~PONT]1.5[#~PONT]</datapoint> (Line A)
</td>
</tr>
<tr type="otherassets" level="1" itemtype="otherassets" hierarchykey="858">
<td colname="1">
<datapoint type="Literal" subtype="Custom" name="Other Assets" value="Other Assets" display="always">Other Assets</datapoint>
</td>
<td colname="2">
<datapoint type="Regular" subtype="" name="PercentOfNetAssets" value="0.1" display="always">[~PONT]0.1[#~PONT]</datapoint> (Line B)
</td>
</tr>
</tbody>
</table>
</section>
我想做的是从(B 行)的 [~PONT] 和 [#~PONT] 标签之间取 0.1,并将其添加到 [~PONT] 和 [#~PONT] 之间的 1.5 ] 标记(A 行),然后抑制包含(B 行)的节点。结果 XML 应如下所示:
<section name="Test" code="" type="Table" fundid="15" subtype="SOI1" style="" xmlns="http://composition.bowne.com/2010/v4">
<table xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" accountperiod="2014-07-31" accountperiodtype="0" code="I2" name="Holdings" fundid="15" type="" cols="2">
<colspec colnum="1" colname="1" />
<colspec colnum="2" colname="2" />
<tbody>
<tr type="categoryhead" level="1" itemtype="categoryhead" categorykey="621" hierarchykey="989">
<td colname="1">
<datapoint type="Regular" subtype="" name="Caption" value="Health Care Equipment & Supplies" display="always">Health Care Equipment & Supplies</datapoint>
</td>
<td colname="2">
<datapoint type="Regular" subtype="" name="PercentOfNetAssets" value="16.6" display="always">16.6</datapoint>
</td>
</tr>
<tr type="categoryhead" level="1" itemtype="categoryhead" categorykey="623" hierarchykey="989">
<td colname="1">
<datapoint type="Literal" subtype="Custom" name="All Others*" value="All Others*" display="always">All Others*</datapoint>
</td>
<td colname="2">
<datapoint type="Regular" subtype="" name="PercentOfNetAssets" value="1.6" display="always">[~PONT]1.6[#~PONT]</datapoint>
</td>
</tr>
</tbody>
</table>
</section>
我知道我可以使用类似的东西来隔离数值:
<xsl:variable name="Value1" select="substring-before(substring-after(string(.),'[~PONT]'),'[#~PONT]')"/>
不幸的是,这就是我所知道的全部。如果这个问题看起来很模糊,我很抱歉,有点难以解释,所以请向我询问更多细节。在此先感谢您的任何建议。顺便说一句,我正在使用 XSLT 版本 1。
- 从身份转换开始,默认情况下所有节点都是
复制到输出。
- 然后添加覆盖以抑制您不再需要的
tr
。在
在下面的示例中,我关闭了 @itemtype='otherassets'
.
- 然后为
datapoint
添加覆盖以接收计数。在
在下面的示例中,我关闭了 categorykey
、itemtype
和
colname
。您可能希望 adapt/generalize 根据您的完整示例,
但此标准适用于您的示例输入,应该会给您一个
感觉需要什么。
此 XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:b="http://composition.bowne.com/2010/v4">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="b:tr[@categorykey='623']/b:td[@colname='2']/b:datapoint">
<xsl:variable name="v1"
select="substring-before(substring-after(string(.),'[~PONT]'),'[#~PONT]')"/>
<xsl:variable name="otherdp"
select="../../../b:tr[@itemtype='otherassets']/b:td[@colname='2']/b:datapoint"/>
<xsl:variable name="v2"
select="substring-before(substring-after(string($otherdp),'[~PONT]'),'[#~PONT]')"/>
<xsl:copy>[~PONT]<xsl:value-of select="$v1 + $v2"/>[#~PONT]</xsl:copy>
</xsl:template>
<xsl:template match="b:tr[@itemtype='otherassets']"/>
</xsl:stylesheet>
产生所需的XML输出:
<?xml version="1.0" encoding="UTF-8"?><section xmlns="http://composition.bowne.com/2010/v4" name="Test" code="" type="Table" fundid="15" subtype="SOI1" style="">
<table xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" accountperiod="2014-07-31" accountperiodtype="0" code="I2" name="Holdings" fundid="15" type="" cols="2">
<colspec colnum="1" colname="1"/>
<colspec colnum="2" colname="2"/>
<tbody>
<tr type="categoryhead" level="1" itemtype="categoryhead" categorykey="621" hierarchykey="989">
<td colname="1">
<datapoint type="Regular" subtype="" name="Caption" value="Health Care Equipment & Supplies" display="always">Health Care Equipment & Supplies</datapoint>
</td>
<td colname="2">
<datapoint type="Regular" subtype="" name="PercentOfNetAssets" value="16.6" display="always">16.6</datapoint>
</td>
</tr>
<tr type="categoryhead" level="1" itemtype="categoryhead" categorykey="623" hierarchykey="989">
<td colname="1">
<datapoint type="Literal" subtype="Custom" name="All Others*" value="All Others*" display="always">All Others*</datapoint>
</td>
<td colname="2">
<datapoint>[~PONT]1.6[#~PONT]</datapoint>
</td>
</tr>
</tbody>
</table>
</section>
我不确定这是否符合要求,因为它们有点不明确,但遵循 XSLT
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tab="http://composition.bowne.com/2010/v4" version="1.0">
<xsl:output method="html" doctype-public="XSLT-compat"
omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tab:datapoint[parent::*/preceding-sibling::*/tab:datapoint[@value='All Others*']]/@value">
<xsl:attribute name="value">
<xsl:value-of select="sum(.) +
sum(//tab:tr[@type='otherassets']/tab:td[2]/tab:datapoint/@value)"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="tab:datapoint[parent::*/preceding-sibling::*/tab:datapoint[@value='All Others*']]/text()">
<xsl:text>[~PONT]</xsl:text>
<xsl:value-of select="sum(./parent::*/@value) + sum(//tab:tr[@type='otherassets']/tab:td[2]/tab:datapoint/@value)"/>
<xsl:text>[#~PONT]</xsl:text>
</xsl:template>
<xsl:template match="tab:tr[@type='otherassets']"/>
</xsl:transform>
当应用于问题中的输入 XML 时会产生输出
<section xmlns="http://composition.bowne.com/2010/v4" name="Test" code="" type="Table" fundid="15" subtype="SOI1" style="">
<table xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" accountperiod="2014-07-31" accountperiodtype="0" code="I2" name="Holdings" fundid="15" type="" cols="2">
<colspec colnum="1" colname="1"></colspec>
<colspec colnum="2" colname="2"></colspec>
<tbody>
<tr type="categoryhead" level="1" itemtype="categoryhead" categorykey="621" hierarchykey="989">
<td colname="1">
<datapoint type="Regular" subtype="" name="Caption" value="Health Care Equipment & Supplies" display="always">Health Care Equipment & Supplies</datapoint>
</td>
<td colname="2">
<datapoint type="Regular" subtype="" name="PercentOfNetAssets" value="16.6" display="always">16.6</datapoint>
</td>
</tr>
<tr type="categoryhead" level="1" itemtype="categoryhead" categorykey="623" hierarchykey="989">
<td colname="1">
<datapoint type="Literal" subtype="Custom" name="All Others*" value="All Others*" display="always">All Others*</datapoint>
</td>
<td colname="2">
<datapoint type="Regular" subtype="" name="PercentOfNetAssets" value="1.6" display="always">[~PONT]1.6[#~PONT]</datapoint> (Line A)
</td>
</tr>
</tbody>
</table>
对于此转换,我在 XSLT 中添加了示例名称空间,用于输入 XML
的附加名称空间 xmlns="http://composition.bowne.com/2010/v4"
xmlns:tab="http://composition.bowne.com/2010/v4"
模板匹配
<xsl:template match="tab:tr[@type='otherassets']"/>
为空并删除此 tr
。
模板匹配
<xsl:template match="tab:datapoint[parent::*/preceding-sibling::*
/tab:datapoint[@value='All Others*']]/@value">
将 value
属性的值更改为此值与 tr[@type='otherassets']
的 datapoint
的值之和:
<xsl:attribute name="value">
<xsl:value-of select="sum(.) +
sum(//tab:tr[@type='otherassets']/tab:td[2]/tab:datapoint/@value)"/>
</xsl:attribute>
要更改文本,模板匹配此tr
text()
<xsl:template match="tab:datapoint[parent::*/preceding-sibling::*
/tab:datapoint[@value='All Others*']]/text()">
不使用问题中建议的 substring-before()
和 substring-after()
,而是使用数据点的 value
属性的值来获取两个值的总和:
<xsl:value-of select="sum(./parent::*/@value) +
sum(//tab:tr[@type='otherassets']/tab:td[2]/tab:datapoint/@value)"/>
这是基于 value
属性的值与 [~PONT][#~PONT]
.
之间文本中的值相同的假设
更新:对于评论中的问题,如果匹配模式中的文本不会被硬编码但参数如何调整:
遵循 XSLT
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tab="http://composition.bowne.com/2010/v4" version="1.0">
<xsl:output method="html" doctype-public="XSLT-compat"
omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:param name="otherRemove" select="'otherassets'"/>
<xsl:param name="otherKeep" select="'All Others*'"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tab:datapoint[@name='PercentOfNetAssets']/@value">
<xsl:choose>
<xsl:when test="parent::tab:datapoint/parent::tab:td
/preceding-sibling::*/tab:datapoint[@value=$otherKeep]">
<xsl:attribute name="value">
<xsl:value-of select="sum(.) +
sum(//tab:tr[@type=$otherRemove]/tab:td[2]/tab:datapoint/@value)"/>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="tab:datapoint[@name='PercentOfNetAssets']/text()">
<xsl:choose>
<xsl:when test="parent::tab:datapoint/parent::tab:td
/preceding-sibling::*/tab:datapoint[@value=$otherKeep]">
<xsl:text>[~PONT]</xsl:text>
<xsl:value-of select="sum(./parent::*/@value) +
sum(//tab:tr[@type=$otherRemove]/tab:td[2]/tab:datapoint/@value)"/>
<xsl:text>[#~PONT]</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="tab:tr">
<xsl:choose>
<xsl:when test="@type=$otherRemove"/>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:transform>
产生相同的结果。
作为调整两个参数
<xsl:param name="otherRemove" select="'otherassets'"/>
<xsl:param name="otherKeep" select="'All Others*'"/>
已添加。
要删除行,现在模板匹配所有 tr
<xsl:template match="tab:tr">
<xsl:choose>
<xsl:when test="@type=$otherRemove"/>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
复制所有 tr
如果它们没有 @type
属性值 $otherRemove
即 otherassets
.
匹配 text()
和 @value
的模板同样调整:
<xsl:template match="tab:datapoint[@name='PercentOfNetAssets']/text()">
和
<xsl:template match="tab:datapoint[@name='PercentOfNetAssets']/@value">
两个模板都签入 <xsl:choose>
<xsl:when test="parent::tab:datapoint/parent::tab:td
/preceding-sibling::*/tab:datapoint[@value=$otherKeep]">
对于与第一个版本的硬编码模板匹配模式相同的条件 $otherKeep
是 All Others*
,调整匹配元素的值并复制所有其他 text()
和 @value
个元素。
我有一个源 XML 文件如下:
<section name="Test" code="" type="Table" fundid="15" subtype="SOI1" style="" xmlns="http://composition.bowne.com/2010/v4">
<table xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" accountperiod="2014-07-31" accountperiodtype="0" code="I2" name="Holdings" fundid="15" type="" cols="2">
<colspec colnum="1" colname="1" />
<colspec colnum="2" colname="2" />
<tbody>
<tr type="categoryhead" level="1" itemtype="categoryhead" categorykey="621" hierarchykey="989">
<td colname="1">
<datapoint type="Regular" subtype="" name="Caption" value="Health Care Equipment & Supplies" display="always">Health Care Equipment & Supplies</datapoint>
</td>
<td colname="2">
<datapoint type="Regular" subtype="" name="PercentOfNetAssets" value="16.6" display="always">16.6</datapoint>
</td>
</tr>
<tr type="categoryhead" level="1" itemtype="categoryhead" categorykey="623" hierarchykey="989">
<td colname="1">
<datapoint type="Literal" subtype="Custom" name="All Others*" value="All Others*" display="always">All Others*</datapoint>
</td>
<td colname="2">
<datapoint type="Regular" subtype="" name="PercentOfNetAssets" value="1.5" display="always">[~PONT]1.5[#~PONT]</datapoint> (Line A)
</td>
</tr>
<tr type="otherassets" level="1" itemtype="otherassets" hierarchykey="858">
<td colname="1">
<datapoint type="Literal" subtype="Custom" name="Other Assets" value="Other Assets" display="always">Other Assets</datapoint>
</td>
<td colname="2">
<datapoint type="Regular" subtype="" name="PercentOfNetAssets" value="0.1" display="always">[~PONT]0.1[#~PONT]</datapoint> (Line B)
</td>
</tr>
</tbody>
</table>
</section>
我想做的是从(B 行)的 [~PONT] 和 [#~PONT] 标签之间取 0.1,并将其添加到 [~PONT] 和 [#~PONT] 之间的 1.5 ] 标记(A 行),然后抑制包含(B 行)的节点。结果 XML 应如下所示:
<section name="Test" code="" type="Table" fundid="15" subtype="SOI1" style="" xmlns="http://composition.bowne.com/2010/v4">
<table xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" accountperiod="2014-07-31" accountperiodtype="0" code="I2" name="Holdings" fundid="15" type="" cols="2">
<colspec colnum="1" colname="1" />
<colspec colnum="2" colname="2" />
<tbody>
<tr type="categoryhead" level="1" itemtype="categoryhead" categorykey="621" hierarchykey="989">
<td colname="1">
<datapoint type="Regular" subtype="" name="Caption" value="Health Care Equipment & Supplies" display="always">Health Care Equipment & Supplies</datapoint>
</td>
<td colname="2">
<datapoint type="Regular" subtype="" name="PercentOfNetAssets" value="16.6" display="always">16.6</datapoint>
</td>
</tr>
<tr type="categoryhead" level="1" itemtype="categoryhead" categorykey="623" hierarchykey="989">
<td colname="1">
<datapoint type="Literal" subtype="Custom" name="All Others*" value="All Others*" display="always">All Others*</datapoint>
</td>
<td colname="2">
<datapoint type="Regular" subtype="" name="PercentOfNetAssets" value="1.6" display="always">[~PONT]1.6[#~PONT]</datapoint>
</td>
</tr>
</tbody>
</table>
</section>
我知道我可以使用类似的东西来隔离数值:
<xsl:variable name="Value1" select="substring-before(substring-after(string(.),'[~PONT]'),'[#~PONT]')"/>
不幸的是,这就是我所知道的全部。如果这个问题看起来很模糊,我很抱歉,有点难以解释,所以请向我询问更多细节。在此先感谢您的任何建议。顺便说一句,我正在使用 XSLT 版本 1。
- 从身份转换开始,默认情况下所有节点都是 复制到输出。
- 然后添加覆盖以抑制您不再需要的
tr
。在 在下面的示例中,我关闭了@itemtype='otherassets'
. - 然后为
datapoint
添加覆盖以接收计数。在 在下面的示例中,我关闭了categorykey
、itemtype
和colname
。您可能希望 adapt/generalize 根据您的完整示例, 但此标准适用于您的示例输入,应该会给您一个 感觉需要什么。
此 XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:b="http://composition.bowne.com/2010/v4">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="b:tr[@categorykey='623']/b:td[@colname='2']/b:datapoint">
<xsl:variable name="v1"
select="substring-before(substring-after(string(.),'[~PONT]'),'[#~PONT]')"/>
<xsl:variable name="otherdp"
select="../../../b:tr[@itemtype='otherassets']/b:td[@colname='2']/b:datapoint"/>
<xsl:variable name="v2"
select="substring-before(substring-after(string($otherdp),'[~PONT]'),'[#~PONT]')"/>
<xsl:copy>[~PONT]<xsl:value-of select="$v1 + $v2"/>[#~PONT]</xsl:copy>
</xsl:template>
<xsl:template match="b:tr[@itemtype='otherassets']"/>
</xsl:stylesheet>
产生所需的XML输出:
<?xml version="1.0" encoding="UTF-8"?><section xmlns="http://composition.bowne.com/2010/v4" name="Test" code="" type="Table" fundid="15" subtype="SOI1" style="">
<table xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" accountperiod="2014-07-31" accountperiodtype="0" code="I2" name="Holdings" fundid="15" type="" cols="2">
<colspec colnum="1" colname="1"/>
<colspec colnum="2" colname="2"/>
<tbody>
<tr type="categoryhead" level="1" itemtype="categoryhead" categorykey="621" hierarchykey="989">
<td colname="1">
<datapoint type="Regular" subtype="" name="Caption" value="Health Care Equipment & Supplies" display="always">Health Care Equipment & Supplies</datapoint>
</td>
<td colname="2">
<datapoint type="Regular" subtype="" name="PercentOfNetAssets" value="16.6" display="always">16.6</datapoint>
</td>
</tr>
<tr type="categoryhead" level="1" itemtype="categoryhead" categorykey="623" hierarchykey="989">
<td colname="1">
<datapoint type="Literal" subtype="Custom" name="All Others*" value="All Others*" display="always">All Others*</datapoint>
</td>
<td colname="2">
<datapoint>[~PONT]1.6[#~PONT]</datapoint>
</td>
</tr>
</tbody>
</table>
</section>
我不确定这是否符合要求,因为它们有点不明确,但遵循 XSLT
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tab="http://composition.bowne.com/2010/v4" version="1.0">
<xsl:output method="html" doctype-public="XSLT-compat"
omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tab:datapoint[parent::*/preceding-sibling::*/tab:datapoint[@value='All Others*']]/@value">
<xsl:attribute name="value">
<xsl:value-of select="sum(.) +
sum(//tab:tr[@type='otherassets']/tab:td[2]/tab:datapoint/@value)"/>
</xsl:attribute>
</xsl:template>
<xsl:template match="tab:datapoint[parent::*/preceding-sibling::*/tab:datapoint[@value='All Others*']]/text()">
<xsl:text>[~PONT]</xsl:text>
<xsl:value-of select="sum(./parent::*/@value) + sum(//tab:tr[@type='otherassets']/tab:td[2]/tab:datapoint/@value)"/>
<xsl:text>[#~PONT]</xsl:text>
</xsl:template>
<xsl:template match="tab:tr[@type='otherassets']"/>
</xsl:transform>
当应用于问题中的输入 XML 时会产生输出
<section xmlns="http://composition.bowne.com/2010/v4" name="Test" code="" type="Table" fundid="15" subtype="SOI1" style="">
<table xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" accountperiod="2014-07-31" accountperiodtype="0" code="I2" name="Holdings" fundid="15" type="" cols="2">
<colspec colnum="1" colname="1"></colspec>
<colspec colnum="2" colname="2"></colspec>
<tbody>
<tr type="categoryhead" level="1" itemtype="categoryhead" categorykey="621" hierarchykey="989">
<td colname="1">
<datapoint type="Regular" subtype="" name="Caption" value="Health Care Equipment & Supplies" display="always">Health Care Equipment & Supplies</datapoint>
</td>
<td colname="2">
<datapoint type="Regular" subtype="" name="PercentOfNetAssets" value="16.6" display="always">16.6</datapoint>
</td>
</tr>
<tr type="categoryhead" level="1" itemtype="categoryhead" categorykey="623" hierarchykey="989">
<td colname="1">
<datapoint type="Literal" subtype="Custom" name="All Others*" value="All Others*" display="always">All Others*</datapoint>
</td>
<td colname="2">
<datapoint type="Regular" subtype="" name="PercentOfNetAssets" value="1.6" display="always">[~PONT]1.6[#~PONT]</datapoint> (Line A)
</td>
</tr>
</tbody>
</table>
对于此转换,我在 XSLT 中添加了示例名称空间,用于输入 XML
的附加名称空间xmlns="http://composition.bowne.com/2010/v4"
xmlns:tab="http://composition.bowne.com/2010/v4"
模板匹配
<xsl:template match="tab:tr[@type='otherassets']"/>
为空并删除此 tr
。
模板匹配
<xsl:template match="tab:datapoint[parent::*/preceding-sibling::*
/tab:datapoint[@value='All Others*']]/@value">
将 value
属性的值更改为此值与 tr[@type='otherassets']
的 datapoint
的值之和:
<xsl:attribute name="value">
<xsl:value-of select="sum(.) +
sum(//tab:tr[@type='otherassets']/tab:td[2]/tab:datapoint/@value)"/>
</xsl:attribute>
要更改文本,模板匹配此tr
text()
<xsl:template match="tab:datapoint[parent::*/preceding-sibling::*
/tab:datapoint[@value='All Others*']]/text()">
不使用问题中建议的 substring-before()
和 substring-after()
,而是使用数据点的 value
属性的值来获取两个值的总和:
<xsl:value-of select="sum(./parent::*/@value) +
sum(//tab:tr[@type='otherassets']/tab:td[2]/tab:datapoint/@value)"/>
这是基于 value
属性的值与 [~PONT][#~PONT]
.
更新:对于评论中的问题,如果匹配模式中的文本不会被硬编码但参数如何调整:
遵循 XSLT
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:tab="http://composition.bowne.com/2010/v4" version="1.0">
<xsl:output method="html" doctype-public="XSLT-compat"
omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:param name="otherRemove" select="'otherassets'"/>
<xsl:param name="otherKeep" select="'All Others*'"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tab:datapoint[@name='PercentOfNetAssets']/@value">
<xsl:choose>
<xsl:when test="parent::tab:datapoint/parent::tab:td
/preceding-sibling::*/tab:datapoint[@value=$otherKeep]">
<xsl:attribute name="value">
<xsl:value-of select="sum(.) +
sum(//tab:tr[@type=$otherRemove]/tab:td[2]/tab:datapoint/@value)"/>
</xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="tab:datapoint[@name='PercentOfNetAssets']/text()">
<xsl:choose>
<xsl:when test="parent::tab:datapoint/parent::tab:td
/preceding-sibling::*/tab:datapoint[@value=$otherKeep]">
<xsl:text>[~PONT]</xsl:text>
<xsl:value-of select="sum(./parent::*/@value) +
sum(//tab:tr[@type=$otherRemove]/tab:td[2]/tab:datapoint/@value)"/>
<xsl:text>[#~PONT]</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="tab:tr">
<xsl:choose>
<xsl:when test="@type=$otherRemove"/>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:transform>
产生相同的结果。
作为调整两个参数
<xsl:param name="otherRemove" select="'otherassets'"/>
<xsl:param name="otherKeep" select="'All Others*'"/>
已添加。
要删除行,现在模板匹配所有 tr
<xsl:template match="tab:tr">
<xsl:choose>
<xsl:when test="@type=$otherRemove"/>
<xsl:otherwise>
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
复制所有 tr
如果它们没有 @type
属性值 $otherRemove
即 otherassets
.
匹配 text()
和 @value
的模板同样调整:
<xsl:template match="tab:datapoint[@name='PercentOfNetAssets']/text()">
和
<xsl:template match="tab:datapoint[@name='PercentOfNetAssets']/@value">
两个模板都签入 <xsl:choose>
<xsl:when test="parent::tab:datapoint/parent::tab:td
/preceding-sibling::*/tab:datapoint[@value=$otherKeep]">
对于与第一个版本的硬编码模板匹配模式相同的条件 $otherKeep
是 All Others*
,调整匹配元素的值并复制所有其他 text()
和 @value
个元素。