我想复制整个文件,通过将其映射到原始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>
答案 0 :(得分:0)
为什么不将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>
答案 1 :(得分:0)
我不确定为什么你不能使用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>
请注意,这不是您问题中显示的结果。正如我在您的问题的评论中已经提到的,如果您想使用author
中的整个file1.xml
节点替代writer
中的file2.xml
节点,则需要提供样式表的逻辑,通过该逻辑,样式表可以识别哪个书的哪个属性用作替换。
例如,如果两个文件只有一个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>