我有一个现有的XML(file1.xml),我必须根据我正在生成的另一个XML(file2.xml)进行更新:file2的内容必须包含在file1中,遵守我稍后将说明的一些规则(内容文件已过度简化,仅显示相关元素):
file1.xml
<?xml version="1.0" encoding="UTF-8"?> <list> <decade lastyear="2012" firstyear="2011"> <year value="2012"> <issue year="2012" number="242" /> <issue year="2012" number="241" /> <issue year="2012" number="240" /> </year> <year value="2011"> <issue year="2011" number="238" /> <issue year="2011" number="237" /> <issue year="2011" number="236" /> <issue year="2011" number="235" /> </year> </decade> <decade lastyear="2010" firstyear="2001"> <year value="2010"> <issue year="2010" number="234" /> <issue year="2010" number="233" /> <issue year="2010" number="232" /> <issue year="2010" number="231" /> <issue year="2010" number="230" /> </year> <year value="2009"> <issue year="2009" number="229" /> <issue year="2009" number="228" /> <issue year="2009" number="227" /> <issue year="2009" number="226" /> <issue year="2009" number="225" /> </year> ... </decade> </list>
file2.xml
<?xml version="1.0" encoding="UTF-8"?> <issue year="2013" number="245" /> ...
如前所述,必须在file1上插入file2的内容,并遵守一些规则:
>如果file1上不存在问题’年份(即,如果插入年份的第一期),则必须创建(已经完成)
>必须在相应年份插入新问题(已完成)
>十年必须更新,以反映最后插入的一年(有这个问题!)
>问题元素必须按年份和编号按降序排序
>如果问题的一年属于新的十年,那么必须创建这个问题以及相应的子年和问题.
>在结果文档中,所有元素必须按降序排序:十年(去年),年(值)和问题(年份和数字)
我正在使用Saxon-HE 9.4.0.6和我迄今为止完成的xsl就是这个:
XSL
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0"> <xsl:output method="xml" omit-xml-declaration="yes" indent="no" encoding="UTF-8"/> <xsl:variable name="up" select="document('../test/ExcelStory/file2.xml')"/> <xsl:variable name="year" select="$up/issue/@year" /> <xsl:template match="@* | node()" > <xsl:copy> <xsl:apply-templates select="@*|node()"> <xsl:sort select="//issue/@year" /> </xsl:apply-templates> </xsl:copy> </xsl:template> <xsl:template match="decade" > <xsl:copy> <xsl:apply-templates select="* | @*"/> <xsl:choose> <xsl:when test="year[1]/@value lt $year"> <year value="{$year}"/> </xsl:when> </xsl:choose> </xsl:copy> </xsl:template> <xsl:template match="year[@value=$year]"> <xsl:copy> <xsl:apply-templates select="* | @*"/> <xsl:apply-templates select="$up/*" /> </xsl:copy> </xsl:template> </xsl:stylesheet>
此样式表假定file1.xml上的内容在读取时已经被排序(就是这种情况).
我想知道我是否必须使用’模式’进行多次传递,首先根据年份创建十年(如果需要),然后在正确的十年(第二次传递??)中插入年份,之后插入关于正确年份(第三次传递??)的问题,最后重新排序所有元素(甚至是另一个传递??)或者是否可以更有效地进行所有必需的处理(一次或两次传递). Michael Key先生建议在其他地方使用xsl:for-each进行这种处理,但在这种情况下我不知道它是否适合更好(更容易?).
即使这个问题看起来与stackoverflow上的其他问题类似,我认为还有一些额外的复杂性使得它值得一读(并且可能会回答,我希望!).
如果您能提供一些有关如何进行的建议或者您是否可以向我指出其他资源,我将不胜感激.
这可能不适用于您的实际用例,因为您说:
(content of files has been oversimplified to show only relevant
elements)
但希望它能给你另一个视角和/或起点.
您可能希望添加标识转换并将xsl:copy-of和xsl:perform-sort替换为xsl:apply-templates.您还需要更新xsl:param以指向外部文件.
<list> <decade lastyear="2012" firstyear="2011"> <year value="2012"> <issue year="2012" number="242" /> <issue year="2012" number="241" /> <issue year="2012" number="240" /> </year> <year value="2011"> <issue year="2011" number="238" /> <issue year="2011" number="237" /> <issue year="2011" number="236" /> <issue year="2011" number="235" /> </year> </decade> <decade lastyear="2010" firstyear="2001"> <year value="2010"> <issue year="2010" number="234" /> <issue year="2010" number="232" /> <issue year="2010" number="233" /> <issue year="2010" number="231" /> <issue year="2010" number="230" /> </year> <year value="2009"> <issue year="2009" number="229" /> <issue year="2009" number="228" /> <issue year="2009" number="227" /> <issue year="2009" number="226" /> <issue year="2009" number="225" /> </year> <year value="2001"> <issue year="2001" number="123" /> </year> </decade> </list>
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs"> <xsl:output indent="yes"/> <xsl:strip-space elements="*"/> <!--This can be changed to point to an external XML file.--> <xsl:param name="up"> <issue year="2013" number="245" /> <issue year="2002" number="135" /> <issue year="2011" number="239" /> </xsl:param> <xsl:template match="/*"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:for-each-group select="($up/issue|*/*/issue)" group-by="floor((number(@year) - 1) div 10)"> <xsl:sort select="@year" data-type="number" order="descending"/> <decade lastyear="{max(current-group()/@year)}" firstyear="{min(current-group()/@year)}"> <xsl:for-each-group select="current-group()" group-by="@year"> <xsl:sort select="current-grouping-key()" data-type="number" order="descending"/> <year value="{current-grouping-key()}"> <xsl:perform-sort select="current-group()"> <xsl:sort select="@number" data-type="number" order="descending"/> </xsl:perform-sort> </year> </xsl:for-each-group> </decade> </xsl:for-each-group> </xsl:copy> </xsl:template> </xsl:stylesheet>
XML输出
<list> <decade lastyear="2013" firstyear="2011"> <year value="2013"> <issue year="2013" number="245"/> </year> <year value="2012"> <issue year="2012" number="242"/> <issue year="2012" number="241"/> <issue year="2012" number="240"/> </year> <year value="2011"> <issue year="2011" number="239"/> <issue year="2011" number="238"/> <issue year="2011" number="237"/> <issue year="2011" number="236"/> <issue year="2011" number="235"/> </year> </decade> <decade lastyear="2010" firstyear="2001"> <year value="2010"> <issue year="2010" number="234"/> <issue year="2010" number="233"/> <issue year="2010" number="232"/> <issue year="2010" number="231"/> <issue year="2010" number="230"/> </year> <year value="2009"> <issue year="2009" number="229"/> <issue year="2009" number="228"/> <issue year="2009" number="227"/> <issue year="2009" number="226"/> <issue year="2009" number="225"/> </year> <year value="2002"> <issue year="2002" number="135"/> </year> <year value="2001"> <issue year="2001" number="123"/> </year> </decade> </list>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。