首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在XML中计算有效行数

在XML中计算有效行数
EN

Stack Overflow用户
提问于 2018-02-07 21:40:59
回答 2查看 810关注 0票数 0

我一直试图将xml转换为html,从而将XML放入HTML表中。

我有以下XML:

代码语言:javascript
复制
<services>
    <service>
        <name>Acupuncture</name>
        <benefits>
            <period>Previous 6 months</period>
            <amount>40</amount>
        </benefits>
        <benefits>
            <period>Current 6 months</period>
            <amount>60</amount>
        </benefits>
    </service>
    <service>
        <name>Artificial Aids</name>
        <benefits>
            <period>Previous 6 months</period>
            <amount>0</amount>
        </benefits>
        <benefits>
            <period>Current 6 months</period>
            <amount>0</amount>
        </benefits>
    </service>
    <service>
        <name>Chiropractic and Osteopathy</name>
        <benefits>
            <period>Previous 6 months</period>
            <amount>100</amount>
        </benefits>
        <benefits>
            <period>Current 6 months</period>
            <amount>25</amount>
        </benefits>
    </service>
    <service>
        <name>Major Dental</name>
        <benefits>
            <period>Previous 6 months</period>
            <amount>1125</amount>
        </benefits>
        <benefits>
            <period>Current 6 months</period>
            <amount>0</amount>
        </benefits>
    </service>
    <service>
        <name>General Dental</name>
        <benefits>
            <period>Previous 6 months</period>
            <amount>75</amount>
        </benefits>
        <benefits>
            <period>Current 6 months</period>
            <amount>23</amount>
        </benefits>
    </service>
    <service>
        <name>Dietetics</name>
        <benefits>
            <period>Previous 6 months</period>
            <amount>0</amount>
        </benefits>
        <benefits>
            <period>Current 6 months</period>
            <amount>0</amount>
        </benefits>
    </service>
    <service>
        <name>Health Management</name>
        <benefits>
            <period>Previous 6 months</period>
            <amount>150</amount>
        </benefits>
        <benefits>
            <period>Current 6 months</period>
            <amount>0</amount>
        </benefits>
    </service>
    <service>
        <name>Hearing Aids</name>
        <benefits>
            <period>Previous 6 months</period>
            <amount>90</amount>
        </benefits>
        <benefits>
            <period>Current 6 months</period>
            <amount>1050</amount>
        </benefits>
    </service>
    <service>
        <name>Natural Therapies</name>
        <benefits>
            <period>Previous 6 months</period>
            <amount>0</amount>
        </benefits>
        <benefits>
            <period>Current 6 months</period>
            <amount>0</amount>
        </benefits>
    </service>
    <service>
        <name>Occupational Therapy</name>
        <benefits>
            <period>Previous 6 months</period>
            <amount>0</amount>
        </benefits>
        <benefits>
            <period>Current 6 months</period>
            <amount>0</amount>
        </benefits>
    </service>
    <service>
        <name>Optical</name>
        <benefits>
            <period>Previous 6 months</period>
            <amount>375</amount>
        </benefits>
        <benefits>
            <period>Current 6 months</period>
            <amount>0</amount>
        </benefits>
    </service>
    <service>
        <name>Gym</name>
        <benefits>
            <period>Lifetime</period>
            <amount>2500</amount>
        </benefits>
    </service>
    <service>
        <name>Pharmacy</name>
        <benefits>
            <period>Previous 6 months</period>
            <amount>0</amount>
        </benefits>
        <benefits>
            <period>Current 6 months</period>
            <amount>0</amount>
        </benefits>
    </service>
    <service>
        <name>Physiotherapy</name>
        <benefits>
            <period>Previous 6 months</period>
            <amount>15</amount>
        </benefits>
        <benefits>
            <period>Current 6 months</period>
            <amount>30</amount>
        </benefits>
    </service>
    <service>
        <name>Podiatry</name>
        <benefits>
            <period>Previous 6 months</period>
            <amount>0</amount>
        </benefits>
        <benefits>
            <period>Current 6 months</period>
            <amount>0</amount>
        </benefits>
    </service>
    <service>
        <name>Psychology</name>
        <benefits>
            <period>Previous 6 months</period>
            <amount>0</amount>
        </benefits>
        <benefits>
            <period>Current 6 months</period>
            <amount>0</amount>
        </benefits>
    </service>
    <service>
        <name>Remedial Massage</name>
        <benefits>
            <period>Previous 6 months</period>
            <amount>0</amount>
        </benefits>
        <benefits>
            <period>Current 6 months</period>
            <amount>0</amount>
        </benefits>
    </service>
    <service>
        <name>Speech Therapy</name>
        <benefits>
            <period>Previous 6 months</period>
            <amount>0</amount>
        </benefits>
        <benefits>
            <period>Current 6 months</period>
            <amount>0</amount>
        </benefits>
    </service>
</services>

我试图将其转换为一个表,并省略过去6个月和当前6个月中具有"0“值的服务,我希望将Gym服务显示为一个单独的列,该列跨越有效的行。

我有以下XSLT:

代码语言:javascript
复制
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="html"/>
  <xsl:template match="/">
    <xsl:variable name="selectNew">
      <xsl:value-of select="count(/services/service/benefits[1][amount !='0'] |/services/service/benefits[2][amount !='0'] )  -1"/>
    </xsl:variable>
    <xsl:variable name="GymCost">
      <xsl:for-each select="/services/service">
        <xsl:if test="name/text()='Gym'">
          <xsl:value-of select="benefits[1]/amount"/>
        </xsl:if>
      </xsl:for-each>
    </xsl:variable>
    <html>
      <body>
        <table border="1" width="100%">
          <xsl:for-each select="/services/service">
            <xsl:if test="not ( benefits[2]/amount/text()='0' and benefits[1]/amount/text()='0') ">
              <xsl:if test="position() = 1">
                <tr>
                  <td style="text-align:center"> Name </td>
                  <td style="text-align:center">Past 6 Months</td>
                  <td style="text-align:center">Current 6 Months</td>
                  <td style="text-align:center"> Gym </td>
                </tr>
              </xsl:if>
              <tr>
                <xsl:if test="not(/name/text()='Gym')">
                  <td>
                    <xsl:value-of select="name"/>
                  </td>
                  <td>
                    <xsl:if test="not(benefits[2]/amount/text()='0')">
                      <xsl:value-of select="benefits[2]/amount"/>
                    </xsl:if>
                  </td>
                  <td>
                    <xsl:if test="not(benefits[1]/amount/text()='0')">
                      <xsl:value-of select="benefits[1]/amount"/>
                    </xsl:if>
                  </td>
                </xsl:if>
                <xsl:if test="position() = 1">
                  <td rowspan="$selectNew"><xsl:value-of select="$GymCost"/>  .. <xsl:value-of select="$selectNew"/>
        </td>
                </xsl:if>
              </tr>
            </xsl:if>
          </xsl:for-each>
        </table>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>

但是,我很难将Gym列显示为表中显示的正确行数。

电流输出

有人能告诉我怎样才能数出有效的行数,这样我才能正确地显示健身房的列吗?

理想输出,其中健身房列跨越9行

EN

回答 2

Stack Overflow用户

发布于 2018-02-08 07:59:17

首先,您的selectNew变量应该是:

代码语言:javascript
复制
<xsl:variable name="selectNew" >
    <xsl:value-of select="count(/services/service[
        benefits[1][amount != 0] or benefits[2][amount != 0]
        ])" />
</xsl:variable>

即计算至少有一个不等于零的后代amount节点的服务节点。

其次,您应该使用属性值模板,而不是这样:

代码语言:javascript
复制
<xsl:if test ="position() = 1">  
    <td rowspan="$selectNew">  
        <xsl:value-of select="$GymCost"/>  .. <xsl:value-of select="$selectNew"/>
    </td>
</xsl:if>

你应该用这个:

代码语言:javascript
复制
<xsl:if test ="position() = 1">  
    <td rowspan="{$selectNew}">  
        <xsl:value-of select="$GymCost"/>  .. <xsl:value-of select="$selectNew"/>
    </td>
</xsl:if>

也许你忘了把牙套放进去了。

整个样式表如下:

代码语言:javascript
复制
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:output method="html"/>

    <xsl:template match="/">
        <xsl:variable name="selectNew" >
            <xsl:value-of select="count(/services/service[benefits[1][amount != 0] or benefits[2][amount != 0]])" />
        </xsl:variable> 

        <xsl:variable name="GymCost" >
            <xsl:for-each select="/services/service">
                <xsl:if test="name/text()='Gym'">   
                    <xsl:value-of select="benefits[1]/amount"/>
                </xsl:if>
            </xsl:for-each>
        </xsl:variable>

        <html>
            <body>
                <table border="1" width="100%">
                    <xsl:for-each select="/services/service">
                        <xsl:if test="not ( benefits[2]/amount/text()='0' and benefits[1]/amount/text()='0') ">
                            <xsl:if test="position() = 1">
                                <tr> <td style="text-align:center"> Name </td> <td style="text-align:center">Past 6 Months</td> <td style="text-align:center">Current 6 Months</td> <td style="text-align:center"> Gym </td> </tr>
                            </xsl:if>  
                            <tr>
                                <xsl:if test="not(/name/text()='Gym')">   

                                    <td> 
                                        <xsl:value-of select="name"/> 
                                    </td> 
                                    <td>               
                                        <xsl:if test="not(benefits[2]/amount/text()='0')">   
                                            <xsl:value-of select="benefits[2]/amount"/>
                                        </xsl:if>
                                    </td>
                                    <td>
                                        <xsl:if test="not(benefits[1]/amount/text()='0')">   
                                            <xsl:value-of select="benefits[1]/amount"/>
                                        </xsl:if>
                                    </td>

                                </xsl:if>
                                <xsl:if test ="position() = 1">  
                                    <td rowspan="{$selectNew}">  
                                        <xsl:value-of select="$GymCost"/>  .. <xsl:value-of select="$selectNew"/>
                                    </td>
                                </xsl:if>  
                            </tr>
                        </xsl:if>
                    </xsl:for-each>
                </table>    
            </body>
        </html>
    </xsl:template>

</xsl:stylesheet>
票数 0
EN

Stack Overflow用户

发布于 2018-02-08 15:20:32

考虑将XSLT拆分为几个模板,一个模板为第一个服务行的样式,然后是第一个服务行的样式。这样就可以避免许多<xsl:if>调用。此外,使用参数从上述节点传递所需的值:

代码语言:javascript
复制
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="html"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/services">
    <html>
      <body>
        <table border="1" width="100%">
            <tr>
              <td style="text-align:center"> Name </td>
              <td style="text-align:center">Past 6 Months</td>
              <td style="text-align:center">Current 6 Months</td>
              <td style="text-align:center"> Gym </td>
            </tr>
            <xsl:apply-templates select="service[benefits[1]/amount &gt; 0 and benefits[1]/amount &gt; 0]">
                <xsl:with-param name="service_count">
                    <xsl:value-of select="count(*[benefits[1]/amount &gt; 0 or benefits[1]/amount &gt; 0])"/>
                </xsl:with-param>
                <xsl:with-param name="gym_amount">
                    <xsl:value-of select="service[name='Gym']/benefits/amount"/>
                </xsl:with-param>
            </xsl:apply-templates>

        </table>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="service[1]">
    <xsl:param name="service_count"/>
    <xsl:param name="gym_amount"/>
    <tr>
        <td><xsl:value-of select="name"/></td>
        <td><xsl:value-of select="benefits[period = 'Previous 6 months']/amount"/></td>
        <td><xsl:value-of select="benefits[period = 'Current 6 months']/amount"/></td>
        <td rowspan='{$service_count}'>
            <xsl:value-of select="concat($gym_amount, '...', $service_count)"/>
        </td>
    </tr>
  </xsl:template>

  <xsl:template match="service[position() &gt; 1]">
    <tr>
        <td><xsl:value-of select="name"/></td>
        <td><xsl:value-of select="benefits[period = 'Previous 6 months']/amount"/></td>
        <td><xsl:value-of select="benefits[period = 'Current 6 months']/amount"/></td>
    </tr>
  </xsl:template>

</xsl:stylesheet>

输出

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48673717

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档