【问题标题】:XSLT. Suppressing a node based on existence of another nodeXSLT。基于另一个节点的存在来抑制一个节点
【发布时间】:2015-01-16 15:01:01
【问题描述】:

我有一个源xml文件如下:

<PortfolioStatement xmlns="http://composition.bowne.com/2010/v4">
<section xmlns="" name="Schedule of Investments" code="" type="Table" fundid="19" subtype="SOI" style="">
    <table xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" accountperiod="2014-10-31" style="SOI_Abbr" accountperiodtype="0" code="Abbreviation" name="Holdings" fundid="19" type="" cols="4">
        <colspec colnum="1" colname="1"/>
        <colspec colnum="2" colname="2"/>
        <colspec colnum="3" colname="3"/>
        <colspec colnum="4" colname="4"/>
        <tbody>
            <tr layoutcode="" type="detail" level="2" itemtype="detail">      (node 1)
                <td colname="1">[~ABSYMB]ABC[#~ABSYMB]</td>
                <td colname="2">American Depositary Receipt</td>
                <td colname="3"/>
                <td colname="4"/>
            </tr>
            <tr layoutcode="" type="detail" level="2" itemtype="detail">
                <td colname="1">[~ABSYMB]LP[#~ABSYMB]</td>
                <td colname="2">Limited Partnership</td>
                <td colname="3"/>
                <td colname="4"/>
            </tr>
            <tr layoutcode="" type="detail" level="2" itemtype="detail">
                <td colname="1">[~ABSYMB]REIT[#~ABSYMB]</td>
                <td colname="2">Real Estate Investment Trust</td>
                <td colname="3"/>
                <td colname="4"/>
            </tr>
            <tr layoutcode="" type="detail" level="2" itemtype="detail">     (node 2)
                <td colname="1">[~ABSYMB]DEF[#~ABSYMB]</td>               
                <td colname="2">Sponsored American Depositary Receipt</td>
                <td colname="3"/>
                <td colname="4"/>
            </tr>
        </tbody>
    </table>
</section>
</PortfolioStatement>

如果节点 2 存在,我想要做的是抑制节点 1(如标记)。节点 1 被定义为在其子 td 节点的标签 [~ABSYMB] 和 [#~ABSYMB] 之间有文本“ABC”。节点 2 被定义为在其子 td 节点的标签 [~ABSYMB] 和 [#~ABSYMB] 之间有文本“DEF”。这将使生成的 xml 看起来像这样:

<PortfolioStatement xmlns="http://composition.bowne.com/2010/v4">
<section xmlns="" name="Schedule of Investments" code="" type="Table" fundid="19" subtype="SOI" style="">
    <table xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" accountperiod="2014-10-31" style="SOI_Abbr" accountperiodtype="0" code="Abbreviation" name="Holdings" fundid="19" type="" cols="4">
        <colspec colnum="1" colname="1"/>
        <colspec colnum="2" colname="2"/>
        <colspec colnum="3" colname="3"/>
        <colspec colnum="4" colname="4"/>
        <tbody>
            <tr layoutcode="" type="detail" level="2" itemtype="detail">
                <td colname="1">[~ABSYMB]LP[#~ABSYMB]</td>
                <td colname="2">Limited Partnership</td>
                <td colname="3"/>
                <td colname="4"/>
            </tr>
            <tr layoutcode="" type="detail" level="2" itemtype="detail">
                <td colname="1">[~ABSYMB]REIT[#~ABSYMB]</td>
                <td colname="2">Real Estate Investment Trust</td>
                <td colname="3"/>
                <td colname="4"/>
            </tr>
            <tr layoutcode="" type="detail" level="2" itemtype="detail">
                <td colname="1">[~ABSYMB]DEF[#~ABSYMB]</td>
                <td colname="2">Sponsored American Depositary Receipt</td>
                <td colname="3"/>
                <td colname="4"/>
            </tr>
        </tbody>
    </table>
</section>
</PortfolioStatement>

文本值“ABC”和“DEF”被设置为参数。到目前为止,我的 xslt 看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:arcml="http://composition.bowne.com/2010/v4"
    xmlns:fn="http://www.w3.org/2005/02/xpath-functions"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:msxml="urn:schemas-microsoft-com:xslt"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  exclude-result-prefixes="fn msxml xsl arcml xsd xsi">

  <xsl:output indent="yes" method="xml" version="1.0" omit-xml-declaration="no"/>

   <!-- Parameters  -->

<xsl:param name="Text1">ABC</xsl:param>
<xsl:param name="Text2">DEF</xsl:param>




<!-- Identity template -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>


<xsl:template match="tr[td]">
    <xsl:choose>

        <xsl:when test="substring-before(substring-after(.,'[~ABSYMB]'),'[#~ABSYMB]')=$Text1">

        </xsl:when>
        <xsl:otherwise>
            <xsl:copy>
                <xsl:apply-templates select="node()|@*"/>
            </xsl:copy>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

</xsl:stylesheet>

这会定位 node1,但我不知道如何检查 node2 是否存在以执行匹配模式覆盖。

我觉得描述我的问题可能比解决问题更令人困惑,为此我深表歉意。非常感谢任何人的任何建议。

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    您需要禁止任何具有

    tr
    • 一个td 孩子,内容为concat('[~ABSYMB]',$Text1,'[#~ABSYMB]')
    • 一个tr 兄弟,而该兄弟又拥有一个td 子元素,内容为concat('[~ABSYMB]',$Text2,'[#~ABSYMB]')

    由于在 XSLT 1.0 中您不能在模板匹配模式中使用变量,所以事情有点复杂,因此您不能使用完全空模板的常用技术来匹配您想要抑制的内容。相反,您需要一个匹配 all tr 元素的模板,然后在该模板中进行逻辑来决定是否保留它们。

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
      <xsl:output indent="yes" method="xml" version="1.0" omit-xml-declaration="no"/>
    
      <!-- Parameters  -->
    
      <xsl:param name="Text1">ABC</xsl:param>
      <xsl:param name="Text2">DEF</xsl:param>
    
      <!-- Identity template, with a name so we can call it -->
      <xsl:template match="node()|@*" name="ident">
        <xsl:copy>
          <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="tr">
        <!-- if this tr is _not_ one we want to suppress... -->
        <xsl:if test="
              not(
                  td = concat('[~ABSYMB]',$Text1,'[#~ABSYMB]')
                and
                  ../tr[td = concat('[~ABSYMB]',$Text2,'[#~ABSYMB]')]
              )">
          <!-- ... then delegate to the identity template -->
          <xsl:call-template name="ident" />
        </xsl:if>
      </xsl:template>
    </xsl:stylesheet>
    

    【讨论】:

      【解决方案2】:

      您可以使用following axe 尝试这种方式:

      <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
          <xsl:output encoding="utf-8" indent="yes" omit-xml-declaration="yes" />
      
          <xsl:template match="@*|node()">
               <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
          </xsl:template>
      
          <xsl:template match="tr[td='[~ABSYMB]ABC[#~ABSYMB]' and following::td='[~ABSYMB]DEF[#~ABSYMB]']"/>
      </xsl:stylesheet>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多