XSLT 将两个输入文件处理成一个输出文件
XSLT Processing two input files into one output file
我正在尝试处理 xml
个文件(docbook
个文档)。文档中有重复的结构,我会从两个文档中提取,参数化,并存储在一个单独的文档中。
为了简化,这里有一个例子:
file1.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<input>
<structure>foo</structure>
<structure>bar</structure>
<structure>baz</structure>
</input>
file2.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<input>
<structure>abc</structure>
<structure>xyz</structure>
<structure>123</structure>
</input>
这是我想要生成的首选输出。
output.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<output>
<structure origin="doc1">foo</structure>
<structure origin="doc1">bar</structure>
<structure origin="doc1">baz</structure>
<structure origin="doc2">abc</structure>
<structure origin="doc2">xyz</structure>
<structure origin="doc2">123</structure>
</output>
现在我不知道如何在 XSLT 中转换两个或多个文档(URI 可以硬编码)和一个附加参数(doc1、doc2 - 这些也可以硬编码)。
如有任何提示,我将不胜感激。
是转换 file1.xml
并仅使用 fn:doc()
读取 file2.xml
,还是设置两个参数并读取两者是一个选择问题,但该概念适用于任何一种方式。加载完这两个文档后,您可以将 XPath 指向 /input/structure
,然后应用模板。
使用 XSLT 2.0,您可以获得 base-uri()
并将其解析为要在 @origin
:
中使用的文件名
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="fn">
<xsl:output indent="yes" />
<xsl:param name="file1" select="'file1.xml'" />
<xsl:param name="file2" select="'file2.xml'" />
<xsl:template match="/">
<output>
<xsl:apply-templates select="(fn:doc($file1) | fn:doc($file2))/input/structure"/>
</output>
</xsl:template>
<xsl:template match="structure">
<xsl:copy>
<xsl:attribute name="origin" select="concat('doc', replace(base-uri(), '.*(\d+).xml', ''))"/>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如果您需要 XSLT 1.0,您可以将文件名作为参数发送:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="fn">
<xsl:output indent="yes" />
<xsl:param name="file1" select="'file1.xml'" />
<xsl:param name="file2" select="'file2.xml'" />
<xsl:template match="/">
<output>
<xsl:call-template name="load-file">
<xsl:with-param name="file" select="$file1"/>
</xsl:call-template>
<xsl:call-template name="load-file">
<xsl:with-param name="file" select="$file2"/>
</xsl:call-template>
</output>
</xsl:template>
<xsl:template name="load-file">
<xsl:param name="file"/>
<xsl:apply-templates select="doc($file)/input/structure">
<xsl:with-param name="file" select="$file"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="structure">
<xsl:param name="file"/>
<xsl:copy>
<xsl:attribute name="origin">
<xsl:value-of select="concat('doc', substring-after(substring-before($file, '.xml'), 'file'))"/>
</xsl:attribute>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我正在尝试处理 xml
个文件(docbook
个文档)。文档中有重复的结构,我会从两个文档中提取,参数化,并存储在一个单独的文档中。
为了简化,这里有一个例子:
file1.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<input>
<structure>foo</structure>
<structure>bar</structure>
<structure>baz</structure>
</input>
file2.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<input>
<structure>abc</structure>
<structure>xyz</structure>
<structure>123</structure>
</input>
这是我想要生成的首选输出。
output.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<output>
<structure origin="doc1">foo</structure>
<structure origin="doc1">bar</structure>
<structure origin="doc1">baz</structure>
<structure origin="doc2">abc</structure>
<structure origin="doc2">xyz</structure>
<structure origin="doc2">123</structure>
</output>
现在我不知道如何在 XSLT 中转换两个或多个文档(URI 可以硬编码)和一个附加参数(doc1、doc2 - 这些也可以硬编码)。
如有任何提示,我将不胜感激。
是转换 file1.xml
并仅使用 fn:doc()
读取 file2.xml
,还是设置两个参数并读取两者是一个选择问题,但该概念适用于任何一种方式。加载完这两个文档后,您可以将 XPath 指向 /input/structure
,然后应用模板。
使用 XSLT 2.0,您可以获得 base-uri()
并将其解析为要在 @origin
:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="fn">
<xsl:output indent="yes" />
<xsl:param name="file1" select="'file1.xml'" />
<xsl:param name="file2" select="'file2.xml'" />
<xsl:template match="/">
<output>
<xsl:apply-templates select="(fn:doc($file1) | fn:doc($file2))/input/structure"/>
</output>
</xsl:template>
<xsl:template match="structure">
<xsl:copy>
<xsl:attribute name="origin" select="concat('doc', replace(base-uri(), '.*(\d+).xml', ''))"/>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
如果您需要 XSLT 1.0,您可以将文件名作为参数发送:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fn="http://www.w3.org/2005/xpath-functions"
exclude-result-prefixes="fn">
<xsl:output indent="yes" />
<xsl:param name="file1" select="'file1.xml'" />
<xsl:param name="file2" select="'file2.xml'" />
<xsl:template match="/">
<output>
<xsl:call-template name="load-file">
<xsl:with-param name="file" select="$file1"/>
</xsl:call-template>
<xsl:call-template name="load-file">
<xsl:with-param name="file" select="$file2"/>
</xsl:call-template>
</output>
</xsl:template>
<xsl:template name="load-file">
<xsl:param name="file"/>
<xsl:apply-templates select="doc($file)/input/structure">
<xsl:with-param name="file" select="$file"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="structure">
<xsl:param name="file"/>
<xsl:copy>
<xsl:attribute name="origin">
<xsl:value-of select="concat('doc', substring-after(substring-before($file, '.xml'), 'file'))"/>
</xsl:attribute>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>