我需要根据预定值拆分以下XML文件,对于此示例,假设我想在创建的每个文件中将“Item”节点限制为三(3)。
这是一个示例输入XML文件:
<Items>
<Item>
<Title>Title 1</Title>
<DueDate>01-02-2008</DueDate>
</Item>
<Item>
<Title>Title 2</Title>
<DueDate>01-02-2009</DueDate>
</Item>
<Item>
<Title>Title 3</Title>
<DueDate>01-02-2010</DueDate>
</Item>
<Item>
<Title>Title 4</Title>
<DueDate>01-02-2011</DueDate>
</Item>
<Item>
<Title>Title 5</Title>
<DueDate>01-02-2012</DueDate>
</Item>
<Item>
<Title>Title 6</Title>
<DueDate>01-02-2013</DueDate>
</Item>
<Item>
<Title>Title 7</Title>
<DueDate>01-02-2013</DueDate>
</Item>
</Items>
基于阈值3的所需输出将是三个文件,其中两个包含3个“项目”,最后一个包含剩余的“项目”,这将是一个。
这是我的XSLT示例,它允许我为每个项目拆分它们,这会产生七个单独的文件,但是,我希望根据“Item”节点的某个限制来限制文件的大小每个文件。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" indent="yes" name="xml" />
<xsl:template match="/">
<xsl:for-each select="//Item">
<xsl:variable name="nTitle" select="Title"/>
<xsl:variable name="filename" select="concat('Items\',$nTitle,'-','.xml')" />
<xsl:value-of select="$filename" />
<xsl:result-document href="{$filename}" format="xml">
<xsl:copy-of select="."/>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:6)
此样式表:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="pItemsNumber" select="3"/>
<xsl:template match="Items">
<xsl:for-each-group select="Item"
group-adjacent="(position()-1) idiv $pItemsNumber">
<xsl:result-document href="Items\{current-grouping-key()}.xml">
<Items>
<xsl:copy-of select="current-group()"/>
</Items>
</xsl:result-document>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
输出:
<?xml version="1.0" encoding="UTF-8"?>
<Items>
<Item>
<Title>Title 1</Title>
<DueDate>01-02-2008</DueDate>
</Item>
<Item>
<Title>Title 2</Title>
<DueDate>01-02-2009</DueDate>
</Item>
<Item>
<Title>Title 3</Title>
<DueDate>01-02-2010</DueDate>
</Item>
</Items>
<?xml version="1.0" encoding="UTF-8"?>
<Items>
<Item>
<Title>Title 4</Title>
<DueDate>01-02-2011</DueDate>
</Item>
<Item>
<Title>Title 5</Title>
<DueDate>01-02-2012</DueDate>
</Item>
<Item>
<Title>Title 6</Title>
<DueDate>01-02-2013</DueDate>
</Item>
</Items>
<?xml version="1.0" encoding="UTF-8"?>
<Items>
<Item>
<Title>Title 7</Title>
<DueDate>01-02-2013</DueDate>
</Item>
</Items>
编辑糟糕!
答案 1 :(得分:0)
此转化:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="pSplitNum" select="3"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Item[position() mod $pSplitNum eq 1]">
<xsl:result-document href=
"file{position()}-{min((position()+$pSplitNum -1, count(/*/Item)))}.xml">
<Items>
<xsl:call-template name="identity"/>
<xsl:apply-templates mode="copy" select=
"following-sibling::Item[position() lt $pSplitNum]"/>
</Items>
</xsl:result-document>
</xsl:template>
<xsl:template match="/*"><xsl:apply-templates/></xsl:template>
<xsl:template match="Item[position() mod $pSplitNum ne 1]"/>
</xsl:stylesheet>
应用于提供的XML文档:
<Items>
<Item>
<Title>Title 1</Title>
<DueDate>01-02-2008</DueDate>
</Item>
<Item>
<Title>Title 2</Title>
<DueDate>01-02-2009</DueDate>
</Item>
<Item>
<Title>Title 3</Title>
<DueDate>01-02-2010</DueDate>
</Item>
<Item>
<Title>Title 4</Title>
<DueDate>01-02-2011</DueDate>
</Item>
<Item>
<Title>Title 5</Title>
<DueDate>01-02-2012</DueDate>
</Item>
<Item>
<Title>Title 6</Title>
<DueDate>01-02-2013</DueDate>
</Item>
<Item>
<Title>Title 7</Title>
<DueDate>01-02-2013</DueDate>
</Item>
</Items>
生成所需的三个xml文件:
Saxon 9.1.0.5J from Saxonica
Java version 1.6.0_22
Stylesheet compilation time: 645 milliseconds
Processing file:/C:/Program%20Files/Java/jre6/bin/marrowtr.xml
Building tree for file:/C:/Program%20Files/Java/jre6/bin/marrowtr.xml using class net.sf.saxon.tinytree.TinyBuilder
Tree built in 10 milliseconds
Tree size: 38 nodes, 119 characters, 0 attributes
Loading net.sf.saxon.event.MessageEmitter
Writing to file:/C:/Program%20Files/Java/jre6/bin/file1-3.xml
Writing to file:/C:/Program%20Files/Java/jre6/bin/file4-6.xml
Writing to file:/C:/Program%20Files/Java/jre6/bin/file7-7.xml
Execution time: 101 milliseconds
Memory used: 11453088
NamePool contents: 20 entries in 20 chains. 6 prefixes, 7 URIs
请注意:
这是身份规则模式的简单应用。
每个Item
开始一个新文件匹配,它会导致顶部元素的包装,处理自身和下一个$ pSplitNum -1(或者剩下的任何内容)最后一组),并将其输出为单个结果文档(文件)。
创建的每个文件的名称为:“filex-y.xml”,其中x
和y
是{的起始和结束索引{1}}文件中写入的元素。
每个未启动新文件的Item
都会被空匹配模板删除。这些元素以“复制”模式处理。
答案 2 :(得分:-1)
您可以实现在循环外声明的计数器。当计数器命中3时,重置它并设置新的文件名。否则,递增并附加到现有文件名。