xsl namespace attribue在子元素中添加空命名空间

时间:2011-06-24 15:44:51

标签: xml xslt

我正在使用xsl element namespace属性在元素中添加命名空间。这会在结果中的子元素中添加空命名空间。

这是将命名空间添加到元素“Auto”中的XSL
编辑 - 我的xsl的简短版本

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
<xsl:output method="xml" indent="no"/>
<xsl:template match="/">
    <xsl:element name="Root">
        <xsl:element name="Auto" namespace="http://www.Root.com/XMLSchema/Auto">
            <xsl:element name="Applicant">
                <xsl:element name="ApplicantType">
                    <xsl:text>Applicant</xsl:text>
                </xsl:element>
            </xsl:element>
        </xsl:element>
        <xsl:element name="Life" namespace="http://www.Root.com/XMLSchema/Auto">
            <xsl:element name="Applicant">
                <xsl:element name="ApplicantType">
                    <xsl:text>Applicant</xsl:text>
                </xsl:element>
            </xsl:element>
        </xsl:element>
    </xsl:element>
</xsl:template>

这是由XSL转换的xml

<Root>
<Auto xmlns="http://www.Root.com/XMLSchema/Auto">
    <Applicant xmlns="">
        <ApplicantType>Applicant</ApplicantType>
    </Applicant>
</Auto>
</Root>

如果看到Applicant元素,则转换添加了xmlns =“”。如何删除这个空命名空间?

4 个答案:

答案 0 :(得分:6)

如果您显示生成ApplicantApplicantType元素的XSL,我们可以更好地帮助您。此外,您在问题描述中混淆了“命名空间”和“命名空间声明”......将这两者分开可能有助于您掌握解决方案

您的XSL代码显然告诉处理器在没有命名空间的情况下输出Applicant元素。 (因此您的代码可能是错误的......您希望Applicant与其父代Auto名称空间位于同一个Applicant名称空间中。)因为没有前缀的Applicant将继承默认名称空间声明它的父,输出XML必须“取消声明”默认的名称空间声明,以便将<xsl:element name="Auto" namespace="http://www.Root.com/XMLSchema/Auto"> <xsl:element name="Applicant"> 放在你请求的没有名称空间中。

例如,如果您的XSL代码显示:

Applicant

然后您告诉XSL在无命名空间中输出<xsl:element name="Auto" namespace="http://www.Root.com/XMLSchema/Auto"> <xsl:element name="Applicant" namespace="http://www.Root.com/XMLSchema/Auto"> 元素,如上所述。要解决此问题,您可以重复命名空间:

<xsl:stylesheet ... xmlns:auto="http://www.Root.com/XMLSchema/Auto">
   ...
      <auto:Auto>
         <auto:Applicant>
            <auto:ApplicantType>
   ...

或者如@empo所说,你可以声明一个命名空间前缀并使用它:

<xsl:stylesheet ... xmlns="http://www.Root.com/XMLSchema/Auto">
   ...
      <xsl:element name="Auto">
         <xsl:element name="Applicant">
   ...

或在样式表(或模板)中使用默认名称空间声明:

{{1}}

答案 1 :(得分:5)

不要在XML的表面语法中考虑名称空间声明,将元素名称视为(uri,localname)对。如果您创建的Applicant元素不在任何命名空间中,但它的父元素位于命名空间中,则序列化程序将添加xmlns =“”以确保您的愿望得到尊重(即让申请者与其父元素位于不同的命名空间中) )。另一方面,如果您希望Applicant位于名称空间“http://www.Root.com/XMLSchema/Auto”中,则需要确保在此命名空间中创建它。你没有展示创建它的代码,所以我们无法确切地说出你做错了什么。

答案 2 :(得分:1)

Applicant和ApplicantType元素都没有命名空间,在这种情况下,空命名空间声明是正确的,或者它们应该与Auto元素位于相同的命名空间中(或者,为了完整性,在另一个命名空间中)。在后一种情况下,您必须修复XSL转换。

答案 3 :(得分:1)

您的输出文件是:

<Root>
<Auto xmlns="http://www.Root.com/XMLSchema/Auto">
    <Applicant xmlns="">
        <ApplicantType>Applicant</ApplicantType>
    </Applicant>
</Auto>
</Root>

如果您查看在转换中指定文字命名空间URI的方式,这是正确的。事实上,您已按以下方式对元素进行了限定:

{}Root
 -{http://www.Root.com/XMLSchema/Auto}Auto
  -{}Applicant
   -{}ApplicantType

您还没有限定 Root,以及ApplicantApplicantType。由于默认情况下,非限定名称被视为属于null namespace(xmlns =“”)的元素,因此输出文档必须至少在那些可能导致文档含糊不清或错误解释的节点中指定此内容。

您可能错过的是,在 XSLT 中,在转换中,您指定特定元素的文字命名空间URI,您仅限定该元素(也不包括其子元素或任何其他后代)。因此,在XSLT中,如果您希望不必为要声明的每个元素定义命名空间,则必须使用全局默认命名空间。这将正确限定命名空间内的每个元素,并省略输出中的大多数命名空间声明。您可能还想使用:

exclude-result-prefixes="#default"

删除多余的命名空间声明。

然后考虑添加带有前缀的全局命名空间,只有在您确实需要它时(例如,您知道输出文档中会出现命名冲突)。

您的问题

  

如何删除此空命名空间?

你现在应该问自己:在哪里限定我的元素(及其后代)(一劳永逸)?