要在xsl中进行子串

时间:2011-02-18 12:10:42

标签: xml xslt

您好我正在使用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>

4 个答案:

答案 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>