0

我的 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,我试图将字符串 '2' 从具有 (tr[@type='detail'] 和 td[@column='1']) 的元素移动到类别标题 (tr [@type='categoryhead ' 和级别='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>
4

1 回答 1

0

这里的术语不太清楚,因为查看输出样本,所发生的只是将“(2)”附加到特定的表格单元格,因此它并没有真正移动任何东西。

此外,您的问题标题提到了子元素,但查看 XML 结构,“详细信息”行实际上是“类别头”行的兄弟。这可能就是问题所在;您如何将“详细信息”行与关联的“类别标题”相关联。一种方法是使用密钥

<xsl:key name="row" 
         match="a:tr[@level != '1']" 
         use="generate-id(preceding-sibling::a:tr[@level=current()/@level - 1][1])" />

这将获取行(除级别 1 之外)并通过具有低级 @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>
于 2013-10-08T08:03:59.227 回答