0

我对 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 清单中看到一个示例。

PS我使用的是xsl 1.0。

4

2 回答 2

2

如果您进行了模式感知 XSLT 2.0 转换,则不需要所有这些type='xs:date'属性:在模式中将其定义为日期就足够了。然后,您可以将属性与

<xsl:template match="attribute(*, xs:date)">

于 2012-09-12T14:29:58.550 回答
1

您可以做的是添加一个模板来匹配任何具有“xs:date”@type 属性的元素,并在其中进行子字符串操作

<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>
于 2012-09-12T13:25:15.500 回答