XSLT2.0 从外部读取信息并分析生成对应文件.采用xsl:for-each-group进行排序输出
2016-08-27 19:47
585 查看
解析器:Saxon
XSLT2.0相对于XSLT1.0增加了unparsed-text() collection() 函数.并且支持xsl:for-each-group来对数据进行排序.
以下代码主要实现的过程是:
A.使用unparsed-text()读取外部文件信息.
B.使用xsl:result-document生成对应信息的XML文件.(使用XSLT2.0 tokenize()函数拆解捕获信息)
C.合并多个XML文件.主要使用到XSLT2.0 collection()函数过滤当前文件夹中的XML文件.
D.使用for-each-group对合并文件中的对象进行排序重新输出.
模拟emoplyees信息存储于empolyees.csv文件中.(Format firstname,lastname,jobTitle,department)
Joe, Fawcett, Developer, IT
Max, Bialystock, CEO, Management
Phineas, Barnum, Head of Sales, Sales and Marketing
Leo, Bloom, Auditor, Accounts
Danny, Ayers, Developer, IT
Carmen, Ghia, PA to the VP of Products, Management
Ulla, Anderson, Head of Promotions, Sales and Marketing
Grace, Hopper, Developer, IT
Bob, Cratchit, Bookkeeper, Accounts
Charles, Babbage, Head of Infrastructure, IT
Roger, De Bris, VP of Products, Management
Willy, Loman, Salesman, Sales and Marketing
Franz, Liebkind, Developer, IT
Luca, Pacioli, Accountant, Accounts
Lorenzo, St. DuBois, Project Manager, IT
A.B.C三步对应的XSLT文件如下:BuildXMLDataFromExtendFile.xslt
可在XSLT文件中设置源文件路径及目标合并文件路径.
该XSLT文件中定义了过滤标签内容空格函数myFunction:removeSpace
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:myData="http://www.ricky.com/myData"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:myFunction="http://www.ricky.com/myFunction"
exclude-result-prefixes="myData myFunction xs">
<!--
content in empolyees.csv
dataFormat: $firstName,$lastName,$jobTitle,$department
Joe, Fawcett, Developer, IT
Max, Bialystock, CEO, Management
Phineas, Barnum, Head of Sales, Sales and Marketing
Leo, Bloom, Auditor, Accounts
Danny, Ayers, Developer, IT
Carmen, Ghia, PA to the VP of Products, Management
Ulla, Anderson, Head of Promotions, Sales and Marketing
Grace, Hopper, Developer, IT
Bob, Cratchit, Bookkeeper, Accounts
Charles, Babbage, Head of Infrastructure, IT
Roger, De Bris, VP of Products, Management
Willy, Loman, Salesman, Sales and Marketing
Franz, Liebkind, Developer, IT
Luca, Pacioli, Accountant, Accounts
Lorenzo, St. DuBois, Project Manager, IT
-->
<xsl:template name="main">
<xsl:variable name="fileLocation" select="myFunction:loadFilePath()" as="xs:string"/>
<xsl:variable name="content" select="unparsed-text($fileLocation)" as="xs:string"/>
<!-- the following code save the empolyee into the separate file -->
<xsl:for-each select="tokenize($content,'\n')">
<xsl:call-template name="saveSeparateEmpolyee">
<xsl:with-param name="empolyeeInfo" select="."/>
</xsl:call-template>
</xsl:for-each>
<!-- the following code save all separate empolyee files into empolyees.xml(location supply by myData:targetFileLocation) -->
<xsl:call-template name="combineAllEmpolyees">
<xsl:with-param name="targetFile" select="myFunction:loadTargetFilePath()"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="saveSeparateEmpolyee">
<xsl:param name="empolyeeInfo" as="xs:string"/>
<xsl:variable name="firstName" select="tokenize($empolyeeInfo,',\s*')[1]" as="xs:string"/>
<xsl:variable name="lastName" select="tokenize($empolyeeInfo,',\s*')[2]" as="xs:string"/>
<xsl:variable name="jobTitle" select="tokenize($empolyeeInfo,',\s*')[3]" as="xs:string"/>
<xsl:variable name="department" select="tokenize($empolyeeInfo,',\s*')[4]" as="xs:string"/>
<!-- the value of department with
(CR (carriage return)) -->
<xsl:result-document href="empolyee-{myFunction:removeSpace($firstName)}-{myFunction:removeSpace($lastName)}.xml">
<empolyee firstName="{$firstName}" lastName="{$lastName}" jobTitle="{$jobTitle}" department="{myFunction:replaceAll($department,'
','')}"/>
</xsl:result-document>
</xsl:template>
<xsl:template name="combineAllEmpolyees">
<xsl:param name="targetFile" as="xs:string"/>
<xsl:result-document href="{$targetFile}">
<allEmpolyees>
<!-- load the empolyees information in separate-xml-file in current directory. format: empolyee-firstName-lastName.xml -->
<xsl:for-each select="collection('?select=empolyee-*.xml')">
<xsl:copy-of select="."/>
</xsl:for-each>
</allEmpolyees>
</xsl:result-document>
</xsl:template>
<!-- location to save all the empolyees information -->
<myData:targetFileLocation>
empolyees.xml
</myData:targetFileLocation>
<!-- location to read the information of all the empolyees-->
<myData:extendsFilePath>
empolyees.csv
</myData:extendsFilePath>
<xsl:function name="myFunction:loadTargetFilePath" as="xs:string">
<xsl:variable name="thisDocument" select="document('')"/>
<xsl:variable name="result" select="myFunction:removeSpace($thisDocument/xsl:stylesheet/myData:targetFileLocation)" as="xs:string"/>
<xsl:value-of select="$result"/>
</xsl:function>
<xsl:function name="myFunction:loadFilePath" as="xs:string">
<xsl:variable name="thisDocument" select="document('')"/>
<xsl:variable name="fileLocation" select="myFunction:removeSpace($thisDocument/xsl:stylesheet/myData:extendsFilePath)" as="xs:string"/>
<xsl:value-of select="$fileLocation"/>
</xsl:function>
<xsl:function name="myFunction:removeSpace" as="xs:string">
<xsl:param name="content" as="xs:string"/>
<xsl:variable name="line" select="'
'" as="xs:string"/>
<xsl:variable name="tab" select="' '" as="xs:string"/>
<xsl:variable name="space" select="' '" as="xs:string"/>
<xsl:variable name="null" select="''" as="xs:string"/>
<xsl:variable name="contentWithoutLine" select="myFunction:replaceAll($content,$line,$null)" as="xs:string"/>
<xsl:variable name="contentWithoutTab" select="myFunction:replaceAll($contentWithoutLine,$tab,$null)" as="xs:string"/>
<xsl:variable name="result" select="myFunction:replaceAll($contentWithoutTab,$space,$null)" as="xs:string"/>
<xsl:value-of select="$result"/>
</xsl:function>
<xsl:function name="myFunction:replaceAll" as="xs:string">
<xsl:param name="content" as="xs:string"/>
<xsl:param name="data" as="xs:string"/>
<xsl:param name="replacement" as="xs:string"/>
<xsl:choose>
<xsl:when test="contains($content,$data)">
<xsl:variable name="before" select="substring-before($content,$data)" as="xs:string"/>
<xsl:variable name="after" select="substring-after($content,$data)" as="xs:string"/>
<xsl:variable name="newContent" select="concat($before,$replacement,$after)" as="xs:string"/>
<xsl:value-of select="myFunction:replaceAll($newContent,$data,$replacement)" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$content" />
</xsl:otherwise>
</xsl:choose>
</xsl:function>
</xsl:stylesheet>
执行命令: java net.sf.saxon.Transform -it:main -xsl:BuildXMLDataFromExtendFile.xslt 当前目录下将生成对应每个empolyee的XML文件及一个汇总文件empolyees.xml(未排序)
接下来编写empolyees.xlst文件来对生成的未排序empolyees.xml进行重新排序
对应empolyees.xslt文件内容如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="allEmpolyees" select="document('empolyees.xml')"/>
<xsl:template name="main">
<!-- Group the empolyees by @department. save as empolyees_group.xml -->
<xsl:result-document href="empolyees_group.xml">
<allEmpolyees>
<xsl:for-each-group select="$allEmpolyees/allEmpolyees/empolyee" group-by="@department">
<!-- sort by @deparment -->
<xsl:sort select="@department" data-type="text"/>
<department department="{current-grouping-key()}">
<xsl:comment>
The following show the empolyees in
<xsl:value-of select="current-grouping-key()"/>
</xsl:comment>
<xsl:apply-templates select="current-group()" mode="showDetail">
<!-- sort by @firstName + @lastName -->
<xsl:sort select="@firstName" data-type="text"/>
<xsl:sort select="@lastName" data-type="text"/>
</xsl:apply-templates>
</department>
</xsl:for-each-group>
</allEmpolyees>
</xsl:result-document>
</xsl:template>
<xsl:template match="empolyee" mode="showDetail">
<empolyee firstName="{@firstName}" lastName="{@lastName}" jobTitle="{@jobTitle}"/>
</xsl:template>
</xsl:stylesheet>执行命令:java net.sf.saxon.Transform -it:main -xsl:empolyees.xslt
执行完毕后将在当前目录下生成empolyees_group.xml文件.
该文件内容已经是对empolyees.xml进行排序处理后的结果.
empolyees_group.xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<allEmpolyees>
<department department="Accounts">
<!--
The following show the empolyees in
Accounts-->
<empolyee firstName="Bob" lastName="Cratchit" jobTitle="Bookkeeper"/>
<empolyee firstName="Leo" lastName="Bloom" jobTitle="Auditor"/>
<empolyee firstName="Luca" lastName="Pacioli" jobTitle="Accountant"/>
</department>
<department department="IT">
<!--
The following show the empolyees in
IT-->
<empolyee firstName="Charles" lastName="Babbage" jobTitle="Head of Infrastructure"/>
<empolyee firstName="Danny" lastName="Ayers" jobTitle="Developer"/>
<empolyee firstName="Franz" lastName="Liebkind" jobTitle="Developer"/>
<empolyee firstName="Grace" lastName="Hopper" jobTitle="Developer"/>
<empolyee firstName="Joe" lastName="Fawcett" jobTitle="Developer"/>
<empolyee firstName="Lorenzo" lastName="St. DuBois" jobTitle="Project Manager"/>
</department>
<department department="Management">
<!--
The following show the empolyees in
Management-->
<empolyee firstName="Carmen" lastName="Ghia" jobTitle="PA to the VP of Products"/>
<empolyee firstName="Max" lastName="Bialystock" jobTitle="CEO"/>
<empolyee firstName="Roger" lastName="De Bris" jobTitle="VP of Products"/>
</department>
<department department="Sales and Marketing">
<!--
The following show the empolyees in
Sales and Marketing-->
<empolyee firstName="Phineas" lastName="Barnum" jobTitle="Head of Sales"/>
<empolyee firstName="Ulla" lastName="Anderson" jobTitle="Head of Promotions"/>
<empolyee firstName="Willy" lastName="Loman" jobTitle="Salesman"/>
</department>
</allEmpolyees><strong>
</strong>
XSLT2.0相对于XSLT1.0增加了unparsed-text() collection() 函数.并且支持xsl:for-each-group来对数据进行排序.
以下代码主要实现的过程是:
A.使用unparsed-text()读取外部文件信息.
B.使用xsl:result-document生成对应信息的XML文件.(使用XSLT2.0 tokenize()函数拆解捕获信息)
C.合并多个XML文件.主要使用到XSLT2.0 collection()函数过滤当前文件夹中的XML文件.
D.使用for-each-group对合并文件中的对象进行排序重新输出.
模拟emoplyees信息存储于empolyees.csv文件中.(Format firstname,lastname,jobTitle,department)
Joe, Fawcett, Developer, IT
Max, Bialystock, CEO, Management
Phineas, Barnum, Head of Sales, Sales and Marketing
Leo, Bloom, Auditor, Accounts
Danny, Ayers, Developer, IT
Carmen, Ghia, PA to the VP of Products, Management
Ulla, Anderson, Head of Promotions, Sales and Marketing
Grace, Hopper, Developer, IT
Bob, Cratchit, Bookkeeper, Accounts
Charles, Babbage, Head of Infrastructure, IT
Roger, De Bris, VP of Products, Management
Willy, Loman, Salesman, Sales and Marketing
Franz, Liebkind, Developer, IT
Luca, Pacioli, Accountant, Accounts
Lorenzo, St. DuBois, Project Manager, IT
A.B.C三步对应的XSLT文件如下:BuildXMLDataFromExtendFile.xslt
可在XSLT文件中设置源文件路径及目标合并文件路径.
该XSLT文件中定义了过滤标签内容空格函数myFunction:removeSpace
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:myData="http://www.ricky.com/myData"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:myFunction="http://www.ricky.com/myFunction"
exclude-result-prefixes="myData myFunction xs">
<!--
content in empolyees.csv
dataFormat: $firstName,$lastName,$jobTitle,$department
Joe, Fawcett, Developer, IT
Max, Bialystock, CEO, Management
Phineas, Barnum, Head of Sales, Sales and Marketing
Leo, Bloom, Auditor, Accounts
Danny, Ayers, Developer, IT
Carmen, Ghia, PA to the VP of Products, Management
Ulla, Anderson, Head of Promotions, Sales and Marketing
Grace, Hopper, Developer, IT
Bob, Cratchit, Bookkeeper, Accounts
Charles, Babbage, Head of Infrastructure, IT
Roger, De Bris, VP of Products, Management
Willy, Loman, Salesman, Sales and Marketing
Franz, Liebkind, Developer, IT
Luca, Pacioli, Accountant, Accounts
Lorenzo, St. DuBois, Project Manager, IT
-->
<xsl:template name="main">
<xsl:variable name="fileLocation" select="myFunction:loadFilePath()" as="xs:string"/>
<xsl:variable name="content" select="unparsed-text($fileLocation)" as="xs:string"/>
<!-- the following code save the empolyee into the separate file -->
<xsl:for-each select="tokenize($content,'\n')">
<xsl:call-template name="saveSeparateEmpolyee">
<xsl:with-param name="empolyeeInfo" select="."/>
</xsl:call-template>
</xsl:for-each>
<!-- the following code save all separate empolyee files into empolyees.xml(location supply by myData:targetFileLocation) -->
<xsl:call-template name="combineAllEmpolyees">
<xsl:with-param name="targetFile" select="myFunction:loadTargetFilePath()"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="saveSeparateEmpolyee">
<xsl:param name="empolyeeInfo" as="xs:string"/>
<xsl:variable name="firstName" select="tokenize($empolyeeInfo,',\s*')[1]" as="xs:string"/>
<xsl:variable name="lastName" select="tokenize($empolyeeInfo,',\s*')[2]" as="xs:string"/>
<xsl:variable name="jobTitle" select="tokenize($empolyeeInfo,',\s*')[3]" as="xs:string"/>
<xsl:variable name="department" select="tokenize($empolyeeInfo,',\s*')[4]" as="xs:string"/>
<!-- the value of department with
(CR (carriage return)) -->
<xsl:result-document href="empolyee-{myFunction:removeSpace($firstName)}-{myFunction:removeSpace($lastName)}.xml">
<empolyee firstName="{$firstName}" lastName="{$lastName}" jobTitle="{$jobTitle}" department="{myFunction:replaceAll($department,'
','')}"/>
</xsl:result-document>
</xsl:template>
<xsl:template name="combineAllEmpolyees">
<xsl:param name="targetFile" as="xs:string"/>
<xsl:result-document href="{$targetFile}">
<allEmpolyees>
<!-- load the empolyees information in separate-xml-file in current directory. format: empolyee-firstName-lastName.xml -->
<xsl:for-each select="collection('?select=empolyee-*.xml')">
<xsl:copy-of select="."/>
</xsl:for-each>
</allEmpolyees>
</xsl:result-document>
</xsl:template>
<!-- location to save all the empolyees information -->
<myData:targetFileLocation>
empolyees.xml
</myData:targetFileLocation>
<!-- location to read the information of all the empolyees-->
<myData:extendsFilePath>
empolyees.csv
</myData:extendsFilePath>
<xsl:function name="myFunction:loadTargetFilePath" as="xs:string">
<xsl:variable name="thisDocument" select="document('')"/>
<xsl:variable name="result" select="myFunction:removeSpace($thisDocument/xsl:stylesheet/myData:targetFileLocation)" as="xs:string"/>
<xsl:value-of select="$result"/>
</xsl:function>
<xsl:function name="myFunction:loadFilePath" as="xs:string">
<xsl:variable name="thisDocument" select="document('')"/>
<xsl:variable name="fileLocation" select="myFunction:removeSpace($thisDocument/xsl:stylesheet/myData:extendsFilePath)" as="xs:string"/>
<xsl:value-of select="$fileLocation"/>
</xsl:function>
<xsl:function name="myFunction:removeSpace" as="xs:string">
<xsl:param name="content" as="xs:string"/>
<xsl:variable name="line" select="'
'" as="xs:string"/>
<xsl:variable name="tab" select="' '" as="xs:string"/>
<xsl:variable name="space" select="' '" as="xs:string"/>
<xsl:variable name="null" select="''" as="xs:string"/>
<xsl:variable name="contentWithoutLine" select="myFunction:replaceAll($content,$line,$null)" as="xs:string"/>
<xsl:variable name="contentWithoutTab" select="myFunction:replaceAll($contentWithoutLine,$tab,$null)" as="xs:string"/>
<xsl:variable name="result" select="myFunction:replaceAll($contentWithoutTab,$space,$null)" as="xs:string"/>
<xsl:value-of select="$result"/>
</xsl:function>
<xsl:function name="myFunction:replaceAll" as="xs:string">
<xsl:param name="content" as="xs:string"/>
<xsl:param name="data" as="xs:string"/>
<xsl:param name="replacement" as="xs:string"/>
<xsl:choose>
<xsl:when test="contains($content,$data)">
<xsl:variable name="before" select="substring-before($content,$data)" as="xs:string"/>
<xsl:variable name="after" select="substring-after($content,$data)" as="xs:string"/>
<xsl:variable name="newContent" select="concat($before,$replacement,$after)" as="xs:string"/>
<xsl:value-of select="myFunction:replaceAll($newContent,$data,$replacement)" />
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$content" />
</xsl:otherwise>
</xsl:choose>
</xsl:function>
</xsl:stylesheet>
执行命令: java net.sf.saxon.Transform -it:main -xsl:BuildXMLDataFromExtendFile.xslt 当前目录下将生成对应每个empolyee的XML文件及一个汇总文件empolyees.xml(未排序)
接下来编写empolyees.xlst文件来对生成的未排序empolyees.xml进行重新排序
对应empolyees.xslt文件内容如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="allEmpolyees" select="document('empolyees.xml')"/>
<xsl:template name="main">
<!-- Group the empolyees by @department. save as empolyees_group.xml -->
<xsl:result-document href="empolyees_group.xml">
<allEmpolyees>
<xsl:for-each-group select="$allEmpolyees/allEmpolyees/empolyee" group-by="@department">
<!-- sort by @deparment -->
<xsl:sort select="@department" data-type="text"/>
<department department="{current-grouping-key()}">
<xsl:comment>
The following show the empolyees in
<xsl:value-of select="current-grouping-key()"/>
</xsl:comment>
<xsl:apply-templates select="current-group()" mode="showDetail">
<!-- sort by @firstName + @lastName -->
<xsl:sort select="@firstName" data-type="text"/>
<xsl:sort select="@lastName" data-type="text"/>
</xsl:apply-templates>
</department>
</xsl:for-each-group>
</allEmpolyees>
</xsl:result-document>
</xsl:template>
<xsl:template match="empolyee" mode="showDetail">
<empolyee firstName="{@firstName}" lastName="{@lastName}" jobTitle="{@jobTitle}"/>
</xsl:template>
</xsl:stylesheet>执行命令:java net.sf.saxon.Transform -it:main -xsl:empolyees.xslt
执行完毕后将在当前目录下生成empolyees_group.xml文件.
该文件内容已经是对empolyees.xml进行排序处理后的结果.
empolyees_group.xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<allEmpolyees>
<department department="Accounts">
<!--
The following show the empolyees in
Accounts-->
<empolyee firstName="Bob" lastName="Cratchit" jobTitle="Bookkeeper"/>
<empolyee firstName="Leo" lastName="Bloom" jobTitle="Auditor"/>
<empolyee firstName="Luca" lastName="Pacioli" jobTitle="Accountant"/>
</department>
<department department="IT">
<!--
The following show the empolyees in
IT-->
<empolyee firstName="Charles" lastName="Babbage" jobTitle="Head of Infrastructure"/>
<empolyee firstName="Danny" lastName="Ayers" jobTitle="Developer"/>
<empolyee firstName="Franz" lastName="Liebkind" jobTitle="Developer"/>
<empolyee firstName="Grace" lastName="Hopper" jobTitle="Developer"/>
<empolyee firstName="Joe" lastName="Fawcett" jobTitle="Developer"/>
<empolyee firstName="Lorenzo" lastName="St. DuBois" jobTitle="Project Manager"/>
</department>
<department department="Management">
<!--
The following show the empolyees in
Management-->
<empolyee firstName="Carmen" lastName="Ghia" jobTitle="PA to the VP of Products"/>
<empolyee firstName="Max" lastName="Bialystock" jobTitle="CEO"/>
<empolyee firstName="Roger" lastName="De Bris" jobTitle="VP of Products"/>
</department>
<department department="Sales and Marketing">
<!--
The following show the empolyees in
Sales and Marketing-->
<empolyee firstName="Phineas" lastName="Barnum" jobTitle="Head of Sales"/>
<empolyee firstName="Ulla" lastName="Anderson" jobTitle="Head of Promotions"/>
<empolyee firstName="Willy" lastName="Loman" jobTitle="Salesman"/>
</department>
</allEmpolyees><strong>
</strong>
相关文章推荐
- Rails Routes中new、collection、member的区别浅析
- 详解Backbone.js框架中的模型Model与其集合collection
- Backbone.js框架中Model与Collection的使用实例
- jQuery选择器源码解读(五):tokenize的解析过程
- jQuery选择器源码解读(三):tokenize方法
- 解决 The Controls collection cannot be modified because the control contains code blocks
- 全面了解JavaScirpt 的垃圾(garbage collection)回收机制
- java Collection 之List学习介绍
- java 的Collection接口实例详解
- Python中Collection的使用小技巧
- java 集合----Map、Collection
- java Collection 之Set使用说明
- 集合操作(一)ArrayList,LinkedList源码分析
- Collection架构
- 用Java集合中的Collections.sort方法对list排序的两种方法
- 新手,正在学Java Collection,瞎写点东西-一个基于链表的stack及其遍历
- 图学java基础篇之集合
- 详解Backbone.js框架中的模型Model与其集合collection
- Backbone.js框架中Model与Collection的使用实例