带设置的 XSLT 输入文件 - 更改多个输出文件
XSLT Input file with settings - change multiple output files
我正在使用 xslt 编辑多个文件。我有一个输入文件,它是我的设置文件,它看起来像这样:
<root>
<file>
<folderin>/var/in/</folderin>
<in>10</in>
<folderout>/var/out</folderout>
<out>20</out>
<name>First file</name>
</file>
</root>
示例文件:
<root>
<element1 id1="10">
...
</element1>
<element2 id2="10" attribute="xyz">
...
</element2>
</root>
还有我的 xslt 文件:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" encoding="utf-8"/>
<xsl:template name="CopyXml" match="/*">
<xsl:for-each select="file">
<xsl:variable name="inputfile" select="concat(folderin, in, '.xml')"/>
<xsl:variable name="outputfile" select="concat(folderout, out, '.xml')"/>
<xsl:result-document method="xml" href="{$outputfile}">
<xsl:copy-of select="document($inputfile)/*"/>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
在 /var/in/ 中有几百个文件,我只想编辑几个文件(在这个例子中 /var/in/10.xml 退出文件 /var/out/20.xml).在新文件中,我想将 id1 和 id2 属性值更改为我的 "out" 参数
我已经成功地用我的 xslt 复制了那些具有足够名称的特定文件,但是我在应用任何模板时遇到问题,因此我可以更改这些文件。我试过使用应用模板,但是我无法让它将这些模板应用到 $outputFile,它要么不做任何事情,要么附加 $outputFile 和设置文件的副本;/有人知道如何做吗?
编辑:
此示例文件的输出:
<root>
<element1 id1="20">
...
</element1>
<element2 id2="20" attribute="xyz">
...
</element2>
</root>
目前您的样式表有:
<xsl:result-document method="xml" href="{$outputfile}">
<xsl:copy-of select="document($inputfile)/*"/>
</xsl:result-document>
因此,您正在创建一个输出文件,其中 将包含输入文件的副本。
为了应用一些修改,您必须对输入文件应用模板,因此您需要:
<xsl:result-document method="xml" href="{$outputfile}">
<!-- further process the input file -->
<xsl:apply-templates select="document($inputfile)/*"/>
</xsl:result-document>
当然,您的样式表 必须包含处理输入文件内容的模板,复制和修改相关部分。
您可以尝试一种渐进的方法来解决您的问题:
- 首先,定义一个样式表,其中包含将单个输入文件转换为单个输出文件的规则
- 一旦这些模板满足您的需要,将它们复制到应用于设置文件的样式表中
此样式表应该满足您的需要:
XSLT 2.0:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" encoding="utf-8"/>
<!-- template to process the settings file -->
<xsl:template match="/">
<xsl:for-each select="root/file">
<xsl:variable name="inputfile" select="concat(folderin, in, '.xml')"/>
<xsl:variable name="outputfile" select="concat(folderout, out, '.xml')"/>
<xsl:result-document method="xml" href="{$outputfile}">
<xsl:apply-templates select="document($inputfile)/*" mode="processFiles">
<xsl:with-param name="outputValue" select="out" tunnel="yes"/>
</xsl:apply-templates>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
<!-- template to process the input files -->
<!-- identity transformation -->
<xsl:template match="* | @* | text()" mode="processFiles">
<xsl:copy>
<xsl:apply-templates select="* | @* | text()" mode="#current"/>
</xsl:copy>
</xsl:template>
<!-- update parameters -->
<xsl:template match="@id1 | @id2" mode="processFiles">
<xsl:param name="outputValue" tunnel="yes"/>
<xsl:attribute name="{name()}">
<xsl:value-of select="$outputValue"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
要点:
- 您不能只复制输入文件,您必须对其应用模板才能更改其中的某些部分
- 在将模板应用于 外部文件时 ,传递了一个名为
outputValue
的参数;使用 tunnel parameter 可以省去每次调用 xsl:apply-templates
时显式传递它的麻烦
- 我使用带有
mode="processFile"
的模板来处理外部文件的内容;在这种简单的情况下并不是绝对必要的,但是在处理更大的样式表时,这有点 "trick" 有助于避免 settings 文件 的模板与外部文件
- 身份模板只复制元素、属性和文本节点
- 属性
id1
和 id2
的特定模板使用隧道参数将现有值替换为所需值
我正在使用 xslt 编辑多个文件。我有一个输入文件,它是我的设置文件,它看起来像这样:
<root>
<file>
<folderin>/var/in/</folderin>
<in>10</in>
<folderout>/var/out</folderout>
<out>20</out>
<name>First file</name>
</file>
</root>
示例文件:
<root>
<element1 id1="10">
...
</element1>
<element2 id2="10" attribute="xyz">
...
</element2>
</root>
还有我的 xslt 文件:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" encoding="utf-8"/>
<xsl:template name="CopyXml" match="/*">
<xsl:for-each select="file">
<xsl:variable name="inputfile" select="concat(folderin, in, '.xml')"/>
<xsl:variable name="outputfile" select="concat(folderout, out, '.xml')"/>
<xsl:result-document method="xml" href="{$outputfile}">
<xsl:copy-of select="document($inputfile)/*"/>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
在 /var/in/ 中有几百个文件,我只想编辑几个文件(在这个例子中 /var/in/10.xml 退出文件 /var/out/20.xml).在新文件中,我想将 id1 和 id2 属性值更改为我的 "out" 参数
我已经成功地用我的 xslt 复制了那些具有足够名称的特定文件,但是我在应用任何模板时遇到问题,因此我可以更改这些文件。我试过使用应用模板,但是我无法让它将这些模板应用到 $outputFile,它要么不做任何事情,要么附加 $outputFile 和设置文件的副本;/有人知道如何做吗?
编辑: 此示例文件的输出:
<root>
<element1 id1="20">
...
</element1>
<element2 id2="20" attribute="xyz">
...
</element2>
</root>
目前您的样式表有:
<xsl:result-document method="xml" href="{$outputfile}">
<xsl:copy-of select="document($inputfile)/*"/>
</xsl:result-document>
因此,您正在创建一个输出文件,其中 将包含输入文件的副本。
为了应用一些修改,您必须对输入文件应用模板,因此您需要:
<xsl:result-document method="xml" href="{$outputfile}">
<!-- further process the input file -->
<xsl:apply-templates select="document($inputfile)/*"/>
</xsl:result-document>
当然,您的样式表 必须包含处理输入文件内容的模板,复制和修改相关部分。
您可以尝试一种渐进的方法来解决您的问题:
- 首先,定义一个样式表,其中包含将单个输入文件转换为单个输出文件的规则
- 一旦这些模板满足您的需要,将它们复制到应用于设置文件的样式表中
此样式表应该满足您的需要:
XSLT 2.0:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes" encoding="utf-8"/>
<!-- template to process the settings file -->
<xsl:template match="/">
<xsl:for-each select="root/file">
<xsl:variable name="inputfile" select="concat(folderin, in, '.xml')"/>
<xsl:variable name="outputfile" select="concat(folderout, out, '.xml')"/>
<xsl:result-document method="xml" href="{$outputfile}">
<xsl:apply-templates select="document($inputfile)/*" mode="processFiles">
<xsl:with-param name="outputValue" select="out" tunnel="yes"/>
</xsl:apply-templates>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
<!-- template to process the input files -->
<!-- identity transformation -->
<xsl:template match="* | @* | text()" mode="processFiles">
<xsl:copy>
<xsl:apply-templates select="* | @* | text()" mode="#current"/>
</xsl:copy>
</xsl:template>
<!-- update parameters -->
<xsl:template match="@id1 | @id2" mode="processFiles">
<xsl:param name="outputValue" tunnel="yes"/>
<xsl:attribute name="{name()}">
<xsl:value-of select="$outputValue"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
要点:
- 您不能只复制输入文件,您必须对其应用模板才能更改其中的某些部分
- 在将模板应用于 外部文件时 ,传递了一个名为
outputValue
的参数;使用 tunnel parameter 可以省去每次调用xsl:apply-templates
时显式传递它的麻烦
- 我使用带有
mode="processFile"
的模板来处理外部文件的内容;在这种简单的情况下并不是绝对必要的,但是在处理更大的样式表时,这有点 "trick" 有助于避免 settings 文件 的模板与外部文件- 身份模板只复制元素、属性和文本节点
- 属性
id1
和id2
的特定模板使用隧道参数将现有值替换为所需值