xslt根据输出xml字符串生成一些结果

时间:2017-12-08 11:36:02

标签: xml xslt xslt-2.0

在我详细解决我的问题之前,我正在使用XSLT将xml转换为另一个。但问题是我想知道在xslt表中是否可以使用生成的xml进行某些计算。

例如,如果我有以下XSLT,

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/root/metadata">
        <xsl:variable name="_countEmp" select="count(header/employees)" />
        <xsl:variable name="_countCont" select="count(header/employees/Contribution)" />
        <XMLDATA>
            <XMLHEADER>
                <SERVICEID>RTLOAD001</SERVICEID>
                <SOURCE>MOBILE</SOURCE>
                <VERSION>2.0</VERSION>
                <RELEASEDATE>20171101</RELEASEDATE>
                <VALIDFROM>20171101</VALIDFROM>
                <VALIDTO>99991231</VALIDTO>
            </XMLHEADER>
            <FORMRETURNS>
                <FORMMAIN>
                    <B_A_JOB_NO/>
                    <LTP_FLAG>N</LTP_FLAG>
                    <LOGIN_ID/>
                </FORMMAIN>
                <FORMDETAILS>
                    <xsl:choose>
                        <xsl:when test="($_taxtype = 'PACO')">
                            <RETURNDATA>
                                <RETURNDETAILS formtype='PAYEA'>
                                    <B_A_CONTRACT_NO/>
                                    <B_FORMTYPE>X</B_FORMTYPE>
                                    <B_POSTING_REF/>
                                </RETURNDETAILS>
                                <ANNEXDETAILS>
                                    <TABLE tablename="PAYEA_L">
                                        <rows>
                                            <xsl:for-each select="header/employees">
                                                <xsl:choose>
                                                    <xsl:when test="(status = 'N' or (status = 'A' and WithHeldAmount > 0))">
                                                        <row>
                                                            <ZDTL_NID><xsl:value-of select="nidCardNumber" /></ZDTL_NID>
                                                            <ZDTL_LASTNAME><xsl:value-of select="lastName" /></ZDTL_LASTNAME>
                                                            <ZDTL_ONAME><xsl:value-of select="firstName" /></ZDTL_ONAME>
                                                        </row>
                                                    </xsl:when>
                                                </xsl:choose>
                                            </xsl:for-each>                                             
                                        </rows>
                                        <numRows><xsl:value-of select="$_countEmp"/></numRows>
                                    </TABLE>
                                </ANNEXDETAILS> 
                            </RETURNDATA>
                        </xsl:when>
                    </xsl:choose>
                </FORMDETAILS>
            </FORMRETURNS>
        </XMLDATA>
    </xsl:template>
</xsl:stylesheet>

如果行节点为空,我想知道是否有可能不输出节点RETURNDATA。

谢谢, 阿什利

2 个答案:

答案 0 :(得分:1)

正如您已将问题标记为我假设您使用XSLT 2.0处理器,然后您当然可以在任何地方使用变量来创建临时树,然后您可以进一步处理,因此在您的例如,XSLT可以创建一个变量

tabWidget->setTabIcon(index, QIcon("iconPath"));

这样你就可以得到处理该变量中主要输入的结果,你只需要确保用例如进一步处理它。

<xsl:template match="/">
    <xsl:variable name="result1">
      <xsl:apply-templates/>
    </xsl:variable>
</xsl:template>

假设您有更多模板来处理主要输入。根据您现有的代码,使用模式分离处理步骤可能会有所帮助。

对于您添加到问题中的示例,如果您将条件<xsl:template match="/"> <xsl:variable name="result1"> <xsl:apply-templates/> </xsl:variable> <!-- example computation --> <xsl:value-of select="'result has', count($result1//foo), 'foo elements'"/> </xsl:template> 添加到您的内部测试中,则似乎没有必要编写两个步骤。

<xsl:when test="($_taxtype = 'PACO')">

然后只有在内部代码生成任何<xsl:when test="($_taxtype = 'PACO') and header/employees[(status = 'N' or (status = 'A' and WithHeldAmount > 0))]"> 元素时才应输出RETURNDATA元素。

答案 1 :(得分:1)

这也是XSLT 3.0的一种方式,它是专为流媒体设计的,但在非流媒体应用程序中也很方便。

I would like to know if it is possible not to output the node RETURNDATA, if the rows node is blank.

首先,如果rows元素为空,则可以避免输出:

<xsl:where-populated>
  <rows>
    <xsl:for-each....>
      ...
    </xsl:for-each>
  </rows>
</xsl:where-populated>

然后你也可以这样做,以避免输出一个空的TABLE:

<xsl:where-populated>
  <TABLE>
    <xsl:where-populated>
      <rows>
        ....

ANNEXDETAILS相同。

然后,如果RETURNDETAILS不会跟随ANNEXDETAILS,则可以避免输出<RETURNDATA> <xsl:on-non-empty> <RETURNDETAILS> .... </RETURNDETAILS> </xsl:on-non-empty> <xsl:where-populated> <ANNEXDETAILS> ....

public class MyInterceptor {
    public static String intercept() {
        return "intercept";
    }
} 

当涉及到这么多元素时会有点复杂,但是当你真的需要一次通过解决方案时它会很方便。