我对xsl和函数式编程都很陌生,所以我将非常感谢这方面的帮助:
我有一个模板,可以转换一些xml并提供输出。问题是,有很多类型 xs:date 的元素,都在不同的上下文中,必须进行本地化。我使用这些xs:dates的子串串联来生成本地化的日期模式字符串。
你可以猜到这会导致大量的复制粘贴“ substring-this和substring-that ”。如何编写一个模板,将自动将xs:date类型的所有元素转换为本地化字符串,保留所有上下文感知转换?
我的xsl是这样的:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html" encoding="utf-8"/>
<xsl:template match="/">
...
<input value="{substring(/select/a/date 9,2)}.{substring(/select/a/date, 6,2)}.{substring(/select/a/date 1,4)}">
...
<!-- assume that following examples are also with substrings -->
<div><xsl:value-of select="different-path/to_date"/></div>
...
<table>
<tr><td><xsl:value-of select="path/to/another/date"/></td></tr>
</table>
<apply-templates/>
</xsl:template>
<xsl:template match="something else">
<!-- more dates here -->
</xsl:template>
</xsl:stylesheet>
我希望我设法让我的问题清楚=)
UPD:以下是xml:
的示例<REQUEST>
<header>
<... />
<ref>
<ref_date type="xs:date">1970-01-01</ref_date>
</ref>
</header>
<general>
<.../>
<info>
<.../>
<date type="xs:date">1970-01-01</date>
<ExpireDate type="xs:date">1970-01-01</ExpireDate>
<RealDate type="xs:date">1970-01-01</RealDate>
<templateDetails>template details</templateDetails>
<effectiveDate type="xs:date">1970-01-01</effectiveDate>
</info>
<party>
<.../>
<date type="xs:date">1970-01-01</date>
</party>
<!-- many other parts of such kind -->
</general>
</REQUEST>
至于输出,有许多不同的选择。主要的是这些值必须设置为不同html对象的值,例如表,输入字段等。您可以在xsl列表中看到一个示例。
P.S。我正在使用xsl 1.0。
答案 0 :(得分:2)
如果您进行了模式感知的XSLT 2.0转换,则不需要所有这些type='xs:date'
属性:在模式中定义它作为日期就足够了。然后,您可以使用
<xsl:template match="attribute(*, xs:date)">
答案 1 :(得分:1)
你可以做的是添加一个模板来匹配任何@type属性为'xs:date'的元素,并在那里进行子串操作
<xsl:template match="*[@type='xs:date']">
<xsl:value-of select="translate(., '-', '/')" />
</xsl:template>
在这种情况下,我只是用斜杠替换连字符作为例子。
然后,而不是使用 xsl:value-of ....
<div><xsl:value-of select="different-path/to_date"/></div>
您可以使用 xsl:apply-templates
<div><xsl:apply-templates select="different-path/to_date"/></div>
将此XSLT视为示例
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="*[@type='xs:date']">
<xsl:copy>
<xsl:value-of select="translate(., '-', '/')" />
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
在这种情况下,所有这些XSLT正在做的是按原样复制XML文档,但更改日期元素。
如果您想将日期模板用于其他元素或值,您也可以将其设为命名模板,如此
<xsl:template match="*[@type='xs:date']" name="date">
<xsl:param name="date" select="." />
<xsl:value-of select="translate($date, '-', '/')" />
</xsl:template>
这样你就可以像函数一样调用它。例如,要格式化数据并添加为属性,您可以执行以下操作:
<input>
<xsl:attribute name="value">
<xsl:call-template name="date">
<xsl:with-param name="date" select="/select/a/date" />
</xsl:call-template>
</xsl:attribute>
</input>