如何改进XSLT 1.0代码实现3个日期格式全部反转?
解决XSLT 1.0中child-2日期反转问题
你的问题核心在于child-2的转换模板没有复用已有的日期反转逻辑,而是直接输出了原始日期值。下面提供两种修复方式,第二种更利于后续维护:
方案1:直接在child-2模板中应用反转逻辑
直接修改child-2模板里的日期属性赋值部分,把原始值替换成反转后的格式:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <!-- identity transform --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 日期属性反转模板 --> <xsl:template match="@DateAttributeParent | @DateAttributeChild-1 | @DateAttributeChild-2"> <xsl:attribute name="{name()}"> <xsl:value-of select="substring-after(substring-after(., '.'), '.')"/> <xsl:text>.</xsl:text> <xsl:value-of select="substring-before(substring-after(., '.'), '.')"/> <xsl:text>.</xsl:text> <xsl:value-of select="substring-before(., '.')"/> </xsl:attribute> </xsl:template> <!-- parent template --> <xsl:template match="parent"> <parent> <xsl:apply-templates select="@*|node()"/> </parent> </xsl:template> <!-- child-1 template(修正原代码匹配错误:源XML是<child>而非<child-1>) --> <xsl:template match="child"> <child> <xsl:for-each select="*"> <xsl:attribute name="{name()}" > <xsl:value-of select="text()"/> </xsl:attribute> </xsl:for-each> <xsl:apply-templates select="@*"/> </child> </xsl:template> <!-- 修改后的child-2模板 --> <xsl:template match="child-2"> <child-2> <xsl:attribute name="attr-3renamed"> <xsl:value-of select="@attr-3"/> </xsl:attribute> <xsl:attribute name="NonRevertingDate"> <!-- 应用日期反转逻辑 --> <xsl:value-of select="substring-after(substring-after(@DateAttributeChild-2, '.'), '.')"/> <xsl:text>.</xsl:text> <xsl:value-of select="substring-before(substring-after(@DateAttributeChild-2, '.'), '.')"/> <xsl:text>.</xsl:text> <xsl:value-of select="substring-before(@DateAttributeChild-2, '.')"/> </xsl:attribute> </child-2> </xsl:template> </xsl:stylesheet>
方案2:封装日期反转逻辑为可复用模板(推荐)
把日期反转逻辑抽成一个命名模板,这样所有需要转换日期的地方都可以调用,避免重复代码,后续修改也更方便:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <!-- 封装日期反转逻辑为命名模板 --> <xsl:template name="reverse-date-format"> <xsl:param name="input-date"/> <xsl:value-of select="substring-after(substring-after($input-date, '.'), '.')"/> <xsl:text>.</xsl:text> <xsl:value-of select="substring-before(substring-after($input-date, '.'), '.')"/> <xsl:text>.</xsl:text> <xsl:value-of select="substring-before($input-date, '.')"/> </xsl:template> <!-- identity transform --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- 日期属性反转模板,调用命名模板 --> <xsl:template match="@DateAttributeParent | @DateAttributeChild-1 | @DateAttributeChild-2"> <xsl:attribute name="{name()}"> <xsl:call-template name="reverse-date-format"> <xsl:with-param name="input-date" select="."/> </xsl:call-template> </xsl:attribute> </xsl:template> <!-- parent template --> <xsl:template match="parent"> <parent> <xsl:apply-templates select="@*|node()"/> </parent> </xsl:template> <!-- child-1 template(修正原代码匹配错误) --> <xsl:template match="child"> <child> <xsl:for-each select="*"> <xsl:attribute name="{name()}" > <xsl:value-of select="text()"/> </xsl:attribute> </xsl:for-each> <xsl:apply-templates select="@*"/> </child> </xsl:template> <!-- 修改后的child-2模板,调用命名模板 --> <xsl:template match="child-2"> <child-2> <xsl:attribute name="attr-3renamed"> <xsl:value-of select="@attr-3"/> </xsl:attribute> <xsl:attribute name="NonRevertingDate"> <xsl:call-template name="reverse-date-format"> <xsl:with-param name="input-date" select="@DateAttributeChild-2"/> </xsl:call-template> </xsl:attribute> </child-2> </xsl:template> </xsl:stylesheet>
预期输出
修改后,child-2的日期也会被正确反转,输出如下:
<root> <parent attr-1="some value" attr-2="abc" DateAttributeParent="2017.11.10"> <child attr-2="some value-2" DateAttributeChild-1="2010.12.09"> </child> <child-2 attr-3renamed="some value-3" NonRevertingDate="2007.11.05" /> </parent> </root>
另外注意:你原代码里的child-1模板匹配的是<child-1>,但源XML里的节点是<child>,我已经在代码里修正了这个笔误,避免影响正常转换。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

