XSLT 映射元素复制的文件



我想复制整个文件,通过将它映射到原始 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.xmlwriter节点的替代品,您将需要提供样式表可以识别哪个书的哪个属性用作替换的逻辑。

例如,如果两个文件只有一个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>

相关内容

  • 没有找到相关文章