将日期从yyyy-mm-dd转换为dd / mm / yyyy,以满足xslt中的空或空日期

时间:2011-06-07 20:09:14

标签: xml xslt

我想将日期的顺序从yyyy-mm-dd更改为dd / mm / yyyy,但是可以满足null或空日期 我用了代码

<!--         Data Submitted -->
<xsl:template match="data_submitted">
<data_submitted>
    <xsl:if test="data_submitted != ''">
            <xsl:value-of select=
           "concat(substring(.,9), '/',
                  (substring(.,6,2)), '/',
                 substring(.,1,4))"
           />
    </xsl:if>
</data_submitted>   
</xsl:template>
<!--                                           -->

但这完全省略了日期。离开时导致在我的结果中出现的空日期为//。我确定我可能在错误的地方或其他地方得到了if,但我想要一个标签出现,即使它是空的。

有什么建议吗?

更新

向所有人道歉,我应该给出初始的xml,因为我正在测试null或空,并且元素中实际上有空格,所以如果我只是放入空格的数量,我的初始翻译就会有效。原始的xml是:data_submitted> </data_submitted>,有8个空格。 test="data_submitted != ' '" 是需要的或: test=".!= ''",每个都有8个空格。

4 个答案:

答案 0 :(得分:1)

有一个“小”的错误。如果你得到它,可以与这个(纠正的)变换进行比较:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="data_submitted">
        <data_submitted>
            <xsl:variable name="year" select="substring-before(.,'-')"/>
            <xsl:variable name="month" select="substring-before(substring-after(.,'-'),'-')"/>
            <xsl:variable name="day" select="substring-after(substring-after(.,'-'),'-')"/>

            <xsl:if test=".!=''">
                <xsl:value-of select=
                    "concat($day,'/',
                    $month,'/',
                    $year)"
                    />
            </xsl:if>
        </data_submitted>   
    </xsl:template>

</xsl:stylesheet>

应用于此样本输入:

<data>
    <data_submitted>
        yyyy-mm-dd
    </data_submitted>
    <data_submitted/>
</data>

返回:

<data>
   <data_submitted>dd/mm/yyyy</data_submitted>
   <data_submitted/>
</data>

弄错了?

模板已经在data_submitted的上下文中,因此在模板测试中,您只需要.来引用匹配的元素。

但是,我建议您在上面的模板上下文中测试空的text()节点,如下所示:

test="boolean(./text())"

或(在您的上下文中相同)

test="boolean(text())"

当且仅当文本字符串长度为0时,这将返回false。

答案 1 :(得分:1)

你没有用“null或empty”来解释你的意思。如果data_submitted元素存在且没有内容,则模板应该有效,但如果data_submitted元素不存在则它将不起作用。要处理不存在和空虚,请将data_submitted != ''替换为not(data_submitted = '')。事实上,作为一般规则,除非您是专家并确切知道它的含义,否则不要在XSLT中使用“!=”。

答案 2 :(得分:1)

您的错误是测试当前(data_submitted)节点的任何data_submitted子节点是否具有非空字符串值。我想源XML文档中的data_submitted元素根本没有任何data_submitted个孩子。

以下是您问题的完整且简短的解决方案,只是覆盖了身份规则/模板:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

    <xsl:template match="data_submitted/text()">
        <xsl:value-of select=
        "concat(substring(.,9),
                 '/',
                 substring(.,6,2),
                 '/',
                 substring(.,1,4)
             )
  "/>
    </xsl:template>
</xsl:stylesheet>

将此转换应用于以下XML文档

<t>
  <a/>
  <b>
     <data_submitted>2011-06-07</data_submitted>
     <data_submitted/>
    </b>
    <data_submitted>1912-05-12</data_submitted>
    <c/>
</t>

产生了想要的正确结果

<t>
   <a/>
   <b>
      <data_submitted>07/06/2011</data_submitted>
      <data_submitted/>
   </b>
   <data_submitted>12/05/1912</data_submitted>
   <c/>
</t>

<强>解释

  1. 身份模板“按原样”复制每个节点

  2. 单个模板覆盖identity rule - 适用于任何data_submitted元素的文字节点子元素。这里的代码生成了想要的转换日期。所有其他节点,甚至包括空data_submitted元素都由标识规则处理,并“按原样”复制到输出。

  3. 记住:在许多情况下,没有必要使用任何XSLT条件指令。

    使用XSLT模板和模式匹配的强大功能。

答案 3 :(得分:0)

通常在测试节点是否存在时,将xpath表达式放在“test”语句中。没有看到你的xml,我猜你可以简单地删除“!=''”,你应该没事。