使XSLT方法在不同时间表现不同(可能带有参数?)

时间:2015-01-14 14:28:13

标签: xml xslt

所以我有代码行:

<xsl:apply-templates select="/MyQuery/Arguments/PhoneNumber" />

从我的表单的“电话号码”字段中输入的任何电话号码中获取XML中的电话号码值。我们称之为555-867-5309。

当运行上面的行时,它使用以下代码调用模板:

<xsl:template match="PhoneNumber">
    <xsl:if test="(. != '')">
        <xsl:call-template name="StringBreakUp"> <!-- Area Code -->
            <xsl:with-param name="text" select="." />
            <xsl:with-param name="current-position" select="2" />
            <xsl:with-param name="remaining-length" select="4" />
            <xsl:with-param name="max-size" select="5" />
        </xsl:call-template>
        <xsl:call-template name="fieldSeparator" />
    </xsl:if>
</xsl:template>

它抓取了电话号码的区号,所以最终得到555,就像我想要的那样。

但我需要一种方法来获得正确的电话号码,也就是说,867-5309。它可以像这样抓住:

<xsl:template match="PhoneNumber2">
    <xsl:if test="(. != '')">
        <xsl:call-template name="StringBreakUp"> <!-- Phone Number -->
            <xsl:with-param name="text" select="." />
            <xsl:with-param name="current-position" select="6" />
            <xsl:with-param name="remaining-length" select="4" />
            <xsl:with-param name="max-size" select="14" />
        </xsl:call-template>
        <xsl:call-template name="fieldSeparator" />
    </xsl:if>
</xsl:template>

不幸的是,我无法像第一个那样调用该模板:

<xsl:apply-templates select="/MyQuery/Arguments/PhoneNumber2" />

因为XML中没有任何内容称为PhoneNumber2。

我能想到的最好的就是致电

<xsl:apply-templates select="/MyQuery/Arguments/PhoneNumber" />

两次。但是,以及问题,我无法想出一种方法来区分需要抓取区号的时间(第一次调用模板)和时间需要正确获取电话号码(第二次调用该方法)。

所以我正在寻找的是:

<xsl:apply-templates select="/MyQuery/Arguments/PhoneNumber" />
<xsl:apply-templates select="/MyQuery/Arguments/PhoneNumber" />

<xsl:template match="NewPhoneNumber">
    <xsl:if test="(. != '')"> **AND FIRST TIME CALLING THIS METHOD**
        <xsl:call-template name="StringBreakUp"> <!-- Area Code -->
            <xsl:with-param name="text" select="." />
            <xsl:with-param name="current-position" select="2" />
            <xsl:with-param name="remaining-length" select="4" />
            <xsl:with-param name="max-size" select="5" />
        </xsl:call-template>
        <xsl:call-template name="fieldSeparator" />
    </xsl:if>
    <xsl:if test="(. != '')"> **AND NOT FIRST TIME REACHING THIS METHOD**
        <xsl:call-template name="StringBreakUp"> <!-- Phone Number -->
            <xsl:with-param name="text" select="." />
            <xsl:with-param name="current-position" select="6" />
            <xsl:with-param name="remaining-length" select="4" />
            <xsl:with-param name="max-size" select="14" />
        </xsl:call-template>
        <xsl:call-template name="fieldSeparator" />
    </xsl:if>
</xsl:template>

但我无法弄清楚如何使用:

<xsl:apply-templates select="/MyQuery/Arguments/PhoneNumber" />

带有参数,以便我可以区分我们通过整个电话号码的时间。

XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template name="Arguments">
    <xsl:call-template name="fieldSeparator" />
    <xsl:apply-templates select="/MyQuery/Arguments/Name" />
    <xsl:apply-templates select="/MyQuery/Arguments/PhoneNumber" />
    <xsl:apply-templates select="/MyQuery/Arguments/PhoneNumber" />
</xsl:template>

<xsl:template match="Name"> 
    <xsl:if test="(. != '')">
        <xsl:copy-of select="." />
        <xsl:call-template name="fieldSeparator" />
    </xsl:if>
</xsl:template>

<xsl:template match="PhoneNumber">
    <xsl:if test="(. != '')">
        <xsl:call-template name="StringBreakUp"> <!-- Area Code -->
            <xsl:with-param name="text" select="." />
            <xsl:with-param name="current-position" select="2" />
            <xsl:with-param name="remaining-length" select="4" />
            <xsl:with-param name="max-size" select="5" />
        </xsl:call-template>
        <xsl:call-template name="fieldSeparator" />
    </xsl:if>
</xsl:template>


<xsl:template match="PhoneNumber2">
    <xsl:if test="(. != '')">
        <xsl:call-template name="StringBreakUp"> <!-- Phone Number -->
            <xsl:with-param name="text" select="." />
            <xsl:with-param name="current-position" select="6" />
            <xsl:with-param name="remaining-length" select="4" />
            <xsl:with-param name="max-size" select="14" />
        </xsl:call-template>
        <xsl:call-template name="fieldSeparator" />
    </xsl:if>
</xsl:template>

</xsl:stylesheet>

XML

< MyQuery >

< Arguments >

    < Name >NNN</ Name >

    < PhoneNumber >(555)867-5309</ PhoneNumber >

</ Arguments >

</ MyQuery >

当前输出     NNN 555 555

渴望输出     NNN 555 867-5309

3 个答案:

答案 0 :(得分:2)

问题问题的答案 - 即如何将两个不同的模板应用于同一节点 - 是使用模式

例如:

<xsl:template match="/">
    <xsl:apply-templates select="MyQuery/Arguments/PhoneNumber" mode="area"/>
    <xsl:apply-templates select="MyQuery/Arguments/PhoneNumber" />
</xsl:template>

<xsl:template match="PhoneNumber" mode="area">
    <!-- code to extract the area -->
</xsl:template>

<xsl:template match="PhoneNumber">
    <!-- code to extract the number -->
</xsl:template>

另一种选择是使用命名模板(直接),例如

<xsl:template match="/">
    <xsl:variable name="pNum" select="MyQuery/Arguments/PhoneNumber"/>
    <xsl:call-template name="get-area">
        <xsl:with-param name="text" select="$pnum"/>
    </xsl:call-template>
    <xsl:call-template name="get-number">
        <xsl:with-param name="text" select="$pnum"/>
    </xsl:call-template>
</xsl:template>

<xsl:template name="get-area">
    <!-- code to extract the area -->
</xsl:template>

<xsl:template match="get-number">
    <!-- code to extract the number -->
</xsl:template>

答案 1 :(得分:1)

到目前为止,老实说我不明白为什么你的代码应该那么复杂。对于简单的字符串操作(比如只获取字符串的一部分),不需要命名模板。

此外,在我看来,拆分字符串并以复杂的方式检索这两个部分是没有意义的 - 只能再次一个接一个地输出它们。

XML输入

<MyQuery>
    <Arguments>
        <Name>NNN</Name>
        <PhoneNumber>(555)867-5309</PhoneNumber>
    </Arguments>
</MyQuery>

XSLT样式表

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="text"/>

    <xsl:strip-space elements="*"/>

    <xsl:template match="Arguments">
      <xsl:value-of select="concat(Name,translate(PhoneNumber,'()','  '))"/>
    </xsl:template>

</xsl:transform>

文字输出

NNN 555 867-5309

答案 2 :(得分:1)

就像马蒂亚斯在他的回答中所说的那样,你使用单独的模板甚至是参数来过度复杂化。已经说过,下面应该做你最初要求的,即基于参数值的不同行为。除非您有理由简化XSL,否则它可能对您有用。

我从XSL下面省略了不相关的部分。

<xsl:template name="Arguments">
    <xsl:call-template name="fieldSeparator" />
    <xsl:apply-templates select="/MyQuery/Arguments/Name" />
    <xsl:apply-templates select="/MyQuery/Arguments/PhoneNumber" >
        <xsl:with-param name="areaCode">true</xsl:with-param>
    </xsl:apply-templates>
    <xsl:apply-templates select="/MyQuery/Arguments/PhoneNumber">
        <xsl:with-param name="areaCode">false</xsl:with-param>
    </xsl:apply-templates>
</xsl:template>

<xsl:template match="PhoneNumber">
    <xsl:param name="areaCode" />
    <xsl:if test="(. != '')">
        <xsl:choose>
            <xsl:when test="$areaCode='true'">
                <xsl:call-template name="StringBreakUp"> <!-- Area Code -->
                    <xsl:with-param name="text" select="." />
                    <xsl:with-param name="current-position" select="2" />
                    <xsl:with-param name="remaining-length" select="4" />
                    <xsl:with-param name="max-size" select="5" />
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <xsl:call-template name="StringBreakUp"> <!-- Phone Number -->
                    <xsl:with-param name="text" select="." />
                    <xsl:with-param name="current-position" select="6" />
                    <xsl:with-param name="remaining-length" select="4" />
                    <xsl:with-param name="max-size" select="14" />
                </xsl:call-template>
                <xsl:call-template name="fieldSeparator" />
            </xsl:otherwise>
            <xsl:call-template name="fieldSeparator" />
        </xsl:choose>
    </xsl:if>
</xsl:template>