2015-01-12 65 views
0

我有一個源XML文件,如下所示:使用XSLT從一個元素添加值到另一個

<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 &amp; Supplies" display="always">Health Care Equipment &amp; 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> 

我想這樣做是取[〜PONT]之間的0.1和[#〜PONT ](B行)標記並將其添加到(A行)上的[〜PONT]和[#〜PONT]標記之間的1.5,然後抑制包含(行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 &amp; Supplies" display="always">Health Care Equipment &amp; 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

什麼確切地標識「A線」和「B線」? –

回答

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 &amp; Supplies" display="always">Health Care Equipment &amp; 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> 

要更改文本中,模板匹配的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屬性的值與[~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

<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]"> 

檢查,這是在相同的條件下:
匹配text()@value模板以同樣的方式被調整第一個版本的硬編碼模板匹配模式爲$otherKeepAll Others*,調整匹配元素的值並複製所有其他text()@value元素。

+0

除了元素文本之外,您還更新了'datapoint/@ value'。我錯過了。 sum()也是一個很好的接觸。 (+1) – kjhughes

+0

謝謝,@matthias_h,這個技巧。 – FordPrefect141

+0

儘管如此,如果不是對文本「其他」和「所有其他」進行硬編碼,文本將以兩個參數的形式進行操作,這樣做有何可能。我知道模板匹配不會讓我在XSLT 1.0中使用變量或參數。 – FordPrefect141

1
  1. 從標識轉換開始,以便默認所有節點都將 複製到輸出。
  2. 然後添加一個覆蓋來抑制你不再需要的tr。在 下面的例子中,我鍵入了@itemtype='otherassets'
  3. 然後爲datapoint添加覆蓋以接收記錄。在 下面的示例中,我鍵入了categorykey,itemtypecolname。您可能希望根據您的完整示例進行調整/概括, 但此準則適用於您的示例輸入,並且應該爲您提供所需內容的 感覺。

這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 &amp; Supplies" display="always">Health Care Equipment &amp; 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> 
+0

感謝您的幫助@kjhughes。 – FordPrefect141

相關問題