XML 使用 XSLT 进行转换:使用递增变量的文件名创建多个输出文件

XML transformation with XSLT: Create multiple output files with file names from incremented variable

我有一个这样的 XML 文件:

<?xml version="1.0" encoding="UTF-8"?>
<xml>
    <letter n="1">
        <p>test 1</p>
    </letter>
    <letter n="2">
        <p>test 2</p>
    </letter>
    <letter n="3">
        <p>test 3</p>
    </letter>
    <letter n="4">
        <p>test 4</p>
    </letter>
</xml>

我当前的样式表没有按预期工作,如下所示:

<?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 name="xml" method="xml" indent="yes"/>
    
    <!-- directory of new files -->
    <xsl:param name="dir">/ex/ex/ex/test</xsl:param>
    
    <!-- new file name = count existing xml files in directory and increment the value by 1 -->
    <xsl:param name="filename"
        select="count(collection('/ex/ex/ex/test?select=*.xml')) + 1"/>
    
    <!-- output xml file for each letter-tag -->
    <xsl:template match="letter">
        <xsl:for-each-group select="." group-by="./@n">
            <xsl:for-each select="current-group()">
                <xsl:result-document format="xml" href="{$dir}/{$filename}.xml">
                    <xsl:copy-of select="./node()"/>
                </xsl:result-document>
            </xsl:for-each>
        </xsl:for-each-group>
    </xsl:template>
    
</xsl:stylesheet>

我想做的:读取要转换的XML文件,找到所有的字母标签,并为每个字母标签创建一个新的XML文件。 (在此示例中,所需的输出将是 4 个新的 XML 文件,第一个 <p>test 1</p>,第二个 <p>test 2</p> 等)文件名应该是现有 XML 输出目录中的文件+1。因此,如果我的输出目录中已经有 10 个文件,我希望将新文件命名为 11.xml、12.xml 等。这是行不通的。

我的问题是收到错误消息“无法将多个结果文档写入同一 URI”。

我想知道的是:如何调整我的样式表以获得我想要的结果,我。 e.我可以做些什么来输出多个 XML 文件,并将递增的 parameter/variable 作为文件名?

如果我没看错你的要求,你想做的是:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:param name="dir">/ex/ex/ex/test</xsl:param>
<xsl:variable name="n" select="count(collection(concat($dir, '?select=*.xml')))"/>

<xsl:template match="/xml">
    <xsl:for-each select="letter">
        <xsl:result-document href="{$dir}/{$n + position()}.xml">
            <xsl:copy-of select="p"/>
        </xsl:result-document>
    </xsl:for-each>
</xsl:template>
  
</xsl:stylesheet>