您好我正在使用XSL将一个XML转换为另一个XML。
我面临的问题是标签内的值是10feb2011
即<date>10feb2011</date>
。
我需要输出:
<date>10</date>
<month>feb</month>
<year>2011</year>
因此我使用了substring
函数,但无法使其正常工作。
我的XML看起来像
<ArrivalDateTime>
<Date>20feb2011<Date>
</ArrivalDateTime>
应将其转换为此格式
<ArrivalDateTime>
<dayOfMonth>10</dayOfMonth>
<month>feb</month>
<year>2011</year>
</ArrivalDateTime>
以下是我写的XSL
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited by XMLSpy® -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<xsl:text><![CDATA[<ArrivalDateTime>]]></xsl:text>
<xsl:text><![CDATA[<dayOfMonth>]]></xsl:text>
<xsl:value-of select='substring("<xsl:value-of select="/ArrivalDateTime/Date"/>",1,2)'/>
<xsl:text><![CDATA[</dayOfMonth>]]></xsl:text>
<xsl:text><![CDATA[<month>]]></xsl:text>
<xsl:value-of select='substring("<xsl:value-of select="/ArrivalDateTime/Date"/>",3,3)'/>
<xsl:text><![CDATA[</month>]]></xsl:text>
<xsl:text><![CDATA[<year>]]></xsl:text>
<xsl:value-of select='substring("<xsl:value-of select="/ArrivalDateTime/Date"/>",5,4)'/>
<xsl:text><![CDATA[</year>]]></xsl:text>
<xsl:text><![CDATA[</ArrivalDateTime>]]></xsl:text></xsl:template>
</xsl:stylesheet>
答案 0 :(得分:9)
您的XSLT看起来过于复杂。只需创建类似的XML节点:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<ArrivalDateTime>
<dayOfMonth>
<xsl:value-of select="substring(/ArrivalDateTime/Date,1,2)"/>
</dayOfMonth>
<month>
<xsl:value-of select="substring(/ArrivalDateTime/Date,3,3)"/>
</month>
<year>
<xsl:value-of select="substring(/ArrivalDateTime/Date,5,4)"/>
</year>
</ArrivalDateTime>
</xsl:template>
</xsl:stylesheet>
您不应该使用CDATA部分在输出文档中创建XML节点。这是不必要的,也可能是危险的,因为它允许生成无效的XML。
请注意,在XPath表达式中,例如在select
属性中,您必须编写有效的XPath。这里不允许使用XML标记。
最好查看一些XSLT教程以开始使用。
答案 1 :(得分:5)
您的子字符串语法不完全正确。您需要使用6,4(而不是5,4)作为年份子串。此外,您不需要使用xsl:text
来发出xml标记。
请改为尝试:
<xsl:template match="/">
<ArrivalDateTime>
<dayOfMonth>
<xsl:value-of select="substring(/ArrivalDateTime/Date,1,2)"/>
</dayOfMonth>
<month>
<xsl:value-of select="substring(/ArrivalDateTime/Date,3,3)"/>
</month>
<year>
<xsl:value-of select="substring(/ArrivalDateTime/Date,6,4)"/>
</year>
</ArrivalDateTime>
</xsl:template>
<强>替代:强>
您甚至可以使用变量来保存日期,这有点整洁:
<xsl:template match="/">
<xsl:variable name="mydate" select="/ArrivalDateTime/Date" />
<ArrivalDateTime>
<dayOfMonth>
<xsl:value-of select="substring($mydate,1,2)"/>
</dayOfMonth>
<month>
<xsl:value-of select="substring($mydate,3,3)"/>
</month>
<year>
<xsl:value-of select="substring($mydate,6,4)"/>
</year>
</ArrivalDateTime>
</xsl:template>
答案 2 :(得分:3)
我意识到这个帖子已经老了,可能没有必要添加另一个答案。
然而,我无法帮助,但是如果这个XML片段是更大文档的一部分,那么先前的答案虽然在技术上对于给定的XML片段是正确的,但是不能解决这个问题。换句话说,这些解决方案在根节点上匹配&#34; /&#34;因此,只有在ArrivalDateTime是文档的根节点时才能工作。实际上,这可能永远不会是这种情况。
递归副本将是一种更具适应性的解决方案:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()|@*|text()">
<xsl:copy>
<xsl:apply-templates select="node()|@*|text()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Date">
<dayOfMonth>
<xsl:value-of select="substring(., 1, 2)"/>
</dayOfMonth>
<month>
<xsl:value-of select="substring(., 3, 3)"/>
</month>
<year>
<xsl:value-of select="substring(., 6)"/>
</year>
</xsl:template>
</xsl:stylesheet>
答案 3 :(得分:2)
你有正确的想法,但事情有点混乱。看起来你期待一些XSLT的评估,因为它正在流出“文本”。
在您的XSLT中,您构建的节点将被序列化为XML。
此变换将产生所需的结果。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes" />
<xsl:template match="/">
<ArrivalDateTime>
<dayOfMonth><xsl:value-of select="substring(/ArrivalDateTime/Date,1,2)"/></dayOfMonth>
<month><xsl:value-of select="substring(/ArrivalDateTime/Date,3,3)"/></month>
<year><xsl:value-of select="substring(/ArrivalDateTime/Date,6,4)"/></year>
</ArrivalDateTime>
</xsl:template>
</xsl:stylesheet>