1

解释我想要做什么有点棘手,所以我将使用一个过于简化的例子。

我有三个 Xsl 模板:A.xsl、B.xsl 和 Common.xsl

A.xsl 和 B.xsl 都使用“xsl:include”来包含 Common.xsl。A.xsl 看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tns="http://MyNamespaceForA" >
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:include href="Common.xslt"/>
    <xsl:template match="/">
        <tns:RootA>
            <xsl:apply-templates select="Root" />
        </tns:RootA>
    </xsl:template>
</xsl:stylesheet>

B.xls 看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tns="http://MyNamespaceForB" >
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:include href="Common.xslt"/>
    <xsl:template match="/">
        <tns:RootB>
            <xsl:apply-templates select="Root" />
        </tns:RootB>
    </xsl:template>
</xsl:stylesheet>

最后,Common.xls 看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<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:template match="Root">
        <tns:Element>
            <tns:SubElement>
            </tns:SubElement>
        </tns:Element>
    </xsl:template>
</xsl:stylesheet>

因此,A 和 B 看起来不同,它们使用相同的命名空间前缀 (tns),但命名空间具有不同的值。A 和 B 包括 Common.xsl,它也使用 tns 命名空间。

换句话说,我希望Common.xsl 中的tns 命名空间取“调用”的值,即A 或B,xsl 文件。

但是,这在使用 XslCompiledTransform 时不起作用,它在 Common.xsl 中抱怨 tns 是一个未声明的命名空间。如果我在 Common.xsl 中声明 tns 命名空间,我需要使用http://MyNamespaceForAor 或http://MyNamespaceForB.

假设我http://MyNamespaceForB在 Common.xsl 中声明 tns。现在,当我使用 A.xsl 时,tns 命名空间的值会发生冲突。结果是 Common.xsl 生成的 XML 元素将具有显式的命名空间值http://MyNamespaceForB. 这当然行不通。

希望我有点清楚我想要做什么。简而言之,我想让“调用”xsl 文件指示包含的 xsl 文件中命名空间的值。

有任何想法吗?/弗雷德里克

4

1 回答 1

1

如果在 Common.xslt 中使用直接命名空间,则必须在同一个文件中声明命名空间,否则它将不是有效的 XML——XSLT 处理器无法加载它。

解决方案是使用xsl:element创建元素并为目标命名空间使用变量

A.xslt

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" indent="yes"/>

  <xsl:variable name="targetNS" select="'http://MyNamespaceForA'"/>

  <xsl:include href="common.xslt"/>

  <xsl:template match="/">
    <xsl:element name="RootA" namespace="{$targetNS}">
      <xsl:apply-templates select="Root"/>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

Common.xslt:

<xsl:stylesheet 
  version="1.0" 
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="Root">
    <xsl:element name="Element" namespace="{$targetNS}">
      <xsl:element name="SubElement" namespace="{$targetNS}">
      </xsl:element>
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>
于 2012-05-30T18:14:36.950 回答