2011-02-18 23 views
2

您好我正在使用XSL将一个XML转换为另一个XML。要在xsl中的子字符串

我面临的问题是标签内的值是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> 

下面是我写的

<?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

这里有一个很好的经验法则:如果你是比较新的XML和XSLT,以及你使用CDATA节,你可能做错事。 – 2011-02-18 19:22:33

回答

4

你的子语法不完全正确的XSL 。年份子字符串需要使用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> 
+0

这是正确的,但为什么变量?为什么不匹配`ArrivalDateTime`元素更具语义正确性? – 2011-02-18 14:48:12

8

你的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教程来开始。

+0

`substring('/ ArrivalDateTime/Date',1,2)`应该是'substring(/ ArrivalDateTime/Date,1,2)`。 – 2011-02-18 12:56:07

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> 
3

我意识到这个线程是旧的,可​​能没有必要添加其他答案。

但是,我不禁要挑剔的是,如果此XML片段是更大文档的一部分,以前的答案在技术上对此给定的XML片段正确无效。换句话说,这些解决方案匹配根节点“/”,因此只有当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>