我想将日期的顺序从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个空格。
答案 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>
<强>解释强>:
身份模板“按原样”复制每个节点
单个模板覆盖identity rule - 适用于任何data_submitted
元素的文字节点子元素。这里的代码生成了想要的转换日期。所有其他节点,甚至包括空data_submitted
元素都由标识规则处理,并“按原样”复制到输出。
记住:在许多情况下,没有必要使用任何XSLT条件指令。
使用XSLT模板和模式匹配的强大功能。
答案 3 :(得分:0)
通常在测试节点是否存在时,将xpath表达式放在“test”语句中。没有看到你的xml,我猜你可以简单地删除“!=''”,你应该没事。