我有一个源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。
答案 0 :(得分:2)
我不确定这是否符合要求,因为它们有点不明确,但是遵循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
属性的值更改为此值的总和以及datapoint
的{{1}}的值:
tr[@type='otherassets']
要更改文字,模板会与此<xsl:attribute name="value">
<xsl:value-of select="sum(.) +
sum(//tab:tr[@type='otherassets']/tab:td[2]/tab:datapoint/@value)"/>
</xsl:attribute>
text()
相匹配
tr
不使用问题中建议的<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
之间文本中的值相同的假设。
更新:对于评论中的问题,如果匹配模式中的文字不是硬编码但参数:
,如何调整此问题遵循XSLT
[~PONT][#~PONT]
产生相同的结果。
调整两个参数
<?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()
和{{1元素。
答案 1 :(得分:1)
tr
。在
在下面的示例中,我键入了@itemtype='otherassets'
。datapoint
添加覆盖以接收记录。在
在下面的示例中,我键入了categorykey
,itemtype
和
colname
。您可能希望根据您的完整示例进行调整/概括,
但是这个标准适用于你的样本输入,应该给你一个
感受到所需要的东西。此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>