mar*_*ton 4 xml xslt xslt-2.0 tei
我有几个单独的XML文件,包含TEI中的历史字母.现在我想将它们合并为一个文件,并以日期作为标准.
A1.xml
<?xml version="1.0" encoding="UTF-8"?>
<TEI xml:id="1">
<teiHeader>
<title>Letter 1</title>
<date when="19990202" n="0"></date>
</teiHeader>
<text>
<p>Content of letter 1</p>
</text>
</TEI>
Run Code Online (Sandbox Code Playgroud)
和第二个文件,A2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<TEI xml:id="2">
<teiHeader>
<title>Letter 1</title>
<date when="20010202" n="0"></date>
</teiHeader>
<text>
<p>Content of letter 2</p>
</text>
</TEI>
Run Code Online (Sandbox Code Playgroud)
第三个,A3.xml:
<?xml version="1.0" encoding="UTF-8"?>
<TEI xml:id="3">
<teiHeader>
<title>Letter 3</title>
<date when="18880101" n="0"></date>
</teiHeader>
<text>
<p>Content of letter 3</p>
</text>
</TEI>
Run Code Online (Sandbox Code Playgroud)
这些文件以连续文件名"A001.xml"到"A999.xml"命名,但不是按所需顺序命名.所以我的首选输出将是单个文件letters.xml:
<?xml version="1.0" encoding="UTF-8"?>
<CORRESPONDENCE>
<TEI xml:id="3">
<teiHeader>
<title>Letter 3</title>
<date when="18880101" n="0"></date>
</teiHeader>
<text>
<p>Content of letter 3</p>
</text>
</TEI>
<TEI xml:id="1">
<teiHeader>
<title>Letter 1</title>
<date when="19990202" n="0"></date>
</teiHeader>
<text>
<p>Content of letter 1</p>
</text>
</TEI>
<TEI xml:id="2">
<teiHeader>
<title>Letter 1</title>
<date when="20010202" n="0"></date>
</teiHeader>
<text>
<p>Content of letter 2</p>
</text>
</TEI>
</CORRESPONDENCE>
Run Code Online (Sandbox Code Playgroud)
尽管我找到了将多个XML文件合并为一个的方法,但我并没有设法使用排序标准来使其工作.这甚至可能吗?
这甚至可能吗?
XSLT旨在能够使用XML执行任何转换任务,并且被认为是图灵完成所以是的,确实可能.
我将假设XSLT 3.0,因为这是演示该版本的新功能的一个很好的例子: xsl:merge.并不是说不可能,但事实并非那么简单.它专门设计用于外部源,但可以使用任何输入,甚至任何大小(它是可流动的).
xsl:merge示例使用上面的示例,以下代码将按该文件模式获取所有XML文件,并创建一个文件,其中包含按日期排序的每个文档的副本.
<!-- xsl:initial-template, new in XSLT 3.0 is like "int main()" in C-style languages -->
<xsl:template name="xsl:initial-template">
<!-- your other code here -->
<result>
<xsl:merge>
<!--
xsl:merge defines the source for merging. It is quite powerful. Here
is a simple example with your data.
With for-each-item you select a sequence of items that need to be merged,
which goes in two steps, first you select a list of anchor items, then
you use the select-attribute to select the sequence you want to merge. Here
a collection of documents is requested, like in OP's question
The select statement selects, with focus on each document, the sequence
of items to be merged. This sequence can be of any length (here it selects all
historic letters)
The merge-key defines the key for which items in the merge sequence are sorted,
an incorrect order will result in an error, unless sort-before-merge
is also specified.
-->
<xsl:merge-source
for-each-item="collection('files/A*.xml')"
select="/root/historic-letter/tei:TEI"
sort-before-merge="true">
<xsl:merge-key
select="tei:teiHeader/tei:data/tei:when"
order="descending"
data-type="number" />
</xsl:merge-source>
<!-- the merge action is called for each item resulting from the select
statement above. Only in this place can you use current-merge-key()
and the current-merge-group() functions, which work similar to their grouping
counterparts.
-->
<xsl:merge-action>
<source original-document="{base-uri()}">
<xsl:copy-of select="." />
</source>
</xsl:merge-action>
</xsl:merge>
</result>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)