开发者

To Substring in xsl

Hi I am converting one XML to another XML using XSL.

The problem I face is the value inside the tag is 10feb2011 i.e <date>10feb2011</date>开发者_运维技巧;.

I need the output to be:

 <date>10</date>
 <month>feb</month>
 <year>2011</year> 

so I used substring function, but could not get it to work.

My XML looks like

<ArrivalDateTime>
  <Date>20feb2011<Date>
</ArrivalDateTime>

It should be converted into this format

 <ArrivalDateTime>
   <dayOfMonth>10</dayOfMonth> 
   <month>feb</month> 
   <year>2011</year> 
 </ArrivalDateTime>

Below is the XSL I wrote

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


Your XSLT looks overly complicated. Simply create the XML nodes like that:

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

You shouldn't be using CDATA sections to create XML nodes in your output document. This is unnecessary and potentially dangerous as it allows the generation of invalid XML.

Please note as well that inside XPath expressions such as within the select attributes you must write valid XPath. XML tags are not allowed here.

Best to check some XSLT tutorial to get started.


Your substring syntax isn't completely correct. You need to use 6,4 (not 5,4) for the year substring. Also you don't need to use xsl:text to emit xml tags.

Try this instead:

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

Alternative:

You can even use a variable to hold the date, which is a bit neater:

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


I realize this thread is old and there's probably no need to add another answer.

However, I can't help but nitpick that the previous answers, while technically correct for this given XML fragment, wouldn't work if this XML fragment were part of a larger document. In other words, these solutions match on the root node "/" and therefore will ONLY work when ArrivalDateTime is the root node of the document. Realistically, this will probably never be the case.

A recursive copy would be a more adaptable solution:

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


You have the right idea, but have things a little mixed up. It looks like you are expecting some pieces of the XSLT to be evaluated as it is streaming out "text".

In your XSLT, you are constructing nodes that will be serialized out as XML.

This transform will produce the desired result.

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜