我想复制整个文件,通过将它映射到原始 xml xsl 文件中的相应元素来操作它的一些元素。假设我有一个表,告诉我 file2 中的哪些元素应该映射到 file2 中的相应元素。例如,file2 中的元素编写器应映射到 file1 中的元素作者。为了简洁起见,假设 file1 如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<Books>
<book1>
<title>Things fall apart</title>
<author name = "Chinua Achebe" nationality = "Nigerian" />
</book1>
</Books>
file2 看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<Books>
<book2>
<title> 1984</title>
<writer>George Orwel</writer>
</book2>
</Books>
我有以下 XSLT:
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Books">
<Bundle>
<id value="test"/>
<resource>
<!-- I am copying into here the entire File2 -->
<xsl:copy-of select="document('file2.xml')/*"/>
</resource>
</Bundle>
<xsl:apply-templates/>
</xsl:template>
现在,我知道我完整复制的 file2 中的元素编写器需要映射到 file1 中的相应元素,即 author,因此最终每当元素编写器出现在 file2 中时,它就会更改为:
<author name = "Chinua Achebe" nationality = "Nigerian" />
这应该是最终的输出。
<Bundle>
<id value="test"/>
<resource>
<?xml version="1.0" encoding="UTF-8"?>
<!-- Here, the copied and modified file2-->
<Books>
<book2>
<title> 1984</title>
<author name = "Chinua Achebe" nationality = "Nigerian" />
</book2>
</Books>
</resource>
</Bundle>
我不确定为什么不能使用 file2.xml
作为转换的源 XML - 或者为什么您甚至需要这里的file1.xml
。
在任何情况下,您都可以轻松地将模板应用于其他文档中的节点(或在其上使用xsl:for-each
)。下面是一个示例:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<Bundle>
<id value="test"/>
<resource>
<xsl:apply-templates select="document('file2.xml')/*"/>
</resource>
</Bundle>
</xsl:template>
<xsl:template match="writer">
<author>
<xsl:apply-templates select="@*|node()"/>
</author>
</xsl:template>
</xsl:stylesheet>
将此转换应用于任何格式正确的 XML 源(请注意,file1.xml
格式不正确)时,结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<Bundle>
<id value="test"/>
<resource>
<Books>
<book2>
<title> 1984</title>
<author>George Orwel</author>
</book2>
</Books>
</resource>
</Bundle>
请注意,这不是您的问题中显示的结果。正如我在对您的问题的评论中已经提到的,如果您想使用 file1.xml
中的整个 author
节点作为 file2.xml
中writer
节点的替代品,您将需要提供样式表可以识别哪个书的哪个属性用作替换的逻辑。
例如,如果两个文件只有一个Book
,则可以使用:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="input" select="/" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<Bundle>
<id value="test"/>
<resource>
<xsl:apply-templates select="document('file2.xml')/*"/>
</resource>
</Bundle>
</xsl:template>
<xsl:template match="writer">
<xsl:copy-of select="$input/Books/book1/author"/>
</xsl:template>
</xsl:stylesheet>
给定格式正确的输入,例如:
.XML
<Books>
<book1>
<title>Things fall apart</title>
<author name = "Chinua Achebe" nationality = "Nigerian"></author>
</book1>
</Books>
这将返回:
<?xml version="1.0" encoding="UTF-8"?>
<Bundle>
<id value="test"/>
<resource>
<Books>
<book2>
<title> 1984</title>
<author name="Chinua Achebe" nationality="Nigerian"/>
</book2>
</Books>
</resource>
</Bundle>
为什么不把file2.xml
的内容放到一个变量中呢?
示例(与您发布的特定文件无关):
<xsl:variable name="params">
<xsl:copy-of select="doc('xslt_params.xml')"/>
</xsl:variable>
然后,您可以访问整个文档中的任何内容。例:
<xsl:variable name="lang">
<xsl:value-of select="$params/descendant::param[1]/@lang1"/>
</xsl:variable>