【问题标题】:xsl namespace attribue add empty namespace in child elementxsl命名空间属性在子元素中添加空命名空间
【发布时间】:2011-06-27 06:37:07
【问题描述】:

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

这是将命名空间添加到元素“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>

如果您看到申请人元素,则转换添加了 xmlns=""。如何移除这个空的命名空间?

【问题讨论】:

  • 好吧!如果您不想要 null 默认命名空间,我只需为所有样式表全局声明想要的命名空间。
  • 那么ApplicantApplicantType 元素从何而来?如果它们来自输入和输出,您希望它们与Auto 元素位于相同的命名空间中,那么您不能将它们复制过来,而是需要对其进行转换。如果您在样式表中创建这些元素,那么只需确保在与 Auto 元素相同的命名空间中创建它们,例如做&lt;Auto xmlns="http://www.Root.com/XMLSchema/Auto"&gt;&lt;Applicant&gt;&lt;ApplicantType&gt;Applicant&lt;/ApplicantType&gt;&lt;/Applicant&gt;&lt;/Auto&gt;.
  • 您需要显示生成ApplicantApplicantType 元素的XSL。此外,您在对问题的描述中混淆了“命名空间”和“命名空间声明”......将这两者分开可能有助于您掌握解决方案。

标签: xml xslt


【解决方案1】:

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

您的 XSL 代码显然是在告诉处理器在无命名空间中输出 Applicant 元素。 (因此您的代码可能是错误的...您希望 Applicant 与其父级位于同一 Auto 命名空间中。)由于没有前缀的 Applicant 将从其父级继承默认命名空间声明,因此输出 XML必须“取消声明”默认命名空间声明,以便按照您的要求将 Applicant 放入任何命名空间中。

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

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

然后你告诉 XSL 在没有命名空间的情况下输出 Applicant 元素,如上所述。要解决此问题,您可以重复命名空间:

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

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

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

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

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

【讨论】:

  • 用短版 xsl 更新票证
  • @Amzath:好的,所以我的“如果你的 XSL 代码说”假设是正确的。我会推荐上面的xmlns:auto= 建议,特别是如果您的&lt;Root&gt; 元素不应该在auto 命名空间中。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      您的输出文档是:

      <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 命名空间 (xmlns="") 的元素,所以您的输出文档必须至少在那些可能导致文档歧义或错误解释的节点中指定这一点。

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

      exclude-result-prefixes="#default"
      

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

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

      您的问题

      如何移除这个空的命名空间?

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-13
        • 2010-10-27
        • 2015-08-30
        • 1970-01-01
        • 1970-01-01
        • 2010-10-20
        相关资源
        最近更新 更多