How to get data from dynamic row
Is it possible to get data after second symbol ;
?
For example I have this XML:
<document>
<line>H;1F;ss;232</line>
<line>H2;1F;sss;232e</line>
<line>H;15F5;sds;232sa;23</line>
<line>Hh;1Fs;scs;232ds</line>
</document>
result should be:
<document>
<line>ss</line>
<line>sss</line>
<line>sds</line>
<line>scs</line>
</document>开发者_开发问答;
I. An XSLT 1.0 solution using FXSL:
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
exclude-result-prefixes="ext">
<xsl:import href="strSplit-to-Words.xsl"/>
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<document>
<xsl:apply-templates/>
</document>
</xsl:template>
<xsl:template match="line">
<xsl:variable name="vwordNodes">
<xsl:call-template name="str-split-to-words">
<xsl:with-param name="pStr" select="."/>
<xsl:with-param name="pDelimiters"
select="';'"/>
</xsl:call-template>
</xsl:variable>
<line>
<xsl:value-of select="ext:node-set($vwordNodes)/*[3]"/>
</line>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<document>
<line>H;1F;ss;232</line>
<line>H2;1F;sss;232e</line>
<line>H;15F5;sds;232sa;23</line>
<line>Hh;1Fs;scs;232ds</line>
</document>
produces the wanted, correct result:
<document>
<line>ss</line>
<line>sss</line>
<line>sds</line>
<line>scs</line>
</document>
Explanation:
We use the
str-split-to-words
template from the FXSL library to split the string value of everyline
element.. Note that it allowis not only a single character, but multiple characters to be specified in itspDelimiters
parameter. In this case we specify only';'
.The result is captured in a variable as an RTF. We convert it to ordinary tree using the
ext:node-set()
extension function. If your XSLT processor doesn't implementext:node-set()
look in its documentation what is the name and namespace of thexxx:node-set()
extension that this particular XSLT processor implements.From the thus obtained tree, we only select and output the 3rd element. Note that this is a short XPath expression and the same short XPath expression would be used even if we wanted the 20th element -- just the index would be 20. This is impossible to achieve in a short and neat form using just a series of
substring-after()
functions.
II. Here is a short and easy XSLT 2.0 solution:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<document>
<xsl:apply-templates/>
</document>
</xsl:template>
<xsl:template match="line">
<document>
<xsl:value-of select="tokenize(., ';')[3]"/>
</document>
</xsl:template>
</xsl:stylesheet>
when this transformation is aplied on the provided XML document:
<document>
<line>H;1F;ss;232</line>
<line>H2;1F;sss;232e</line>
<line>H;15F5;sds;232sa;23</line>
<line>Hh;1Fs;scs;232ds</line>
</document>
the wanted, correct result is produced:
<document>
<document>ss</document>
<document>sss</document>
<document>sds</document>
<document>scs</document>
</document>
Use substring-before
and substring-after
functions, i.e.:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<xsl:template match="line">
<xsl:copy>
<xsl:value-of select="substring-before(substring-after(substring-after(., ';'), ';'), ';')"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Result:
<document>
<line>ss</line>
<line>sss</line>
<line>sds</line>
<line>scs</line>
</document>
精彩评论