【问题标题】:xsl:include template with no default namespace causes xmlns=""xsl:include 没有默认命名空间的模板导致 xmlns=""
【发布时间】:2011-02-04 19:36:39
【问题描述】:

xsl:include 和默认命名空间存在问题,导致最终 xml 文档包含具有 xmlns=""

的节点

在这个 synario 中,我有 1 个源文档,它是普通的旧 XML 并且没有命名空间:

<?xml version="1.0" encoding="UTF-8"?>
<SourceDoc>
    <Description>Hello I'm the source description</Description>
    <Description>Hello I'm the source description 2</Description>
    <Description/>
    <Title>Hello I'm the title</Title>
</SourceDoc>

此文档被转换为 2 个不同的 xml 文档,每个文档都有它们自己的默认命名空间

第一个文件:

<?xml version="1.0" encoding="utf-8"?>
<OutputDocType1 xmlns="http://MadeupNS1">
   <Description >Hello I'm the source description</Description>
   <Description>Hello I'm the source description 2</Description>
   <Title>Hello I'm the title</Title>
</OutputDocType1>

第二份文件:

<?xml version="1.0" encoding="utf-8"?>
<OutputDocType2 xmlns="http://MadeupNS2">
   <Description>Hello I'm the source description</Description>
   <Description>Hello I'm the source description 2</Description>
   <DocTitle>Hello I'm the title</DocTitle>
</OutputDocType2>

我希望能够在两种转换中重复使用 descriptions 模板。因为这两种文档的逻辑相同。为此,我创建了一个模板文件,该文件在其他 2 个转换中是 xsl:included:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

    <xsl:template match="Description[. != '']">
        <Description>
            <xsl:value-of select="."/>
        </Description>
    </xsl:template>
</xsl:stylesheet>

现在这里的问题是这个共享转换不能有一个默认的命名空间,因为它会根据调用转换调用它而有所不同。

例如对于第一个文档转换:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output indent="yes" method="xml"/>
    <xsl:template match="SourceDoc">
        <OutputDocType1 xmlns="http://MadeupNS1">

            <xsl:apply-templates select="Description"/>
            <xsl:if test="Title">
                <Title>
                    <xsl:value-of select="Title"/>
                </Title>
            </xsl:if>
        </OutputDocType1>
    </xsl:template>

    <xsl:include href="Template.xsl"/>
</xsl:stylesheet>

这实际上输出如下:

<?xml version="1.0" encoding="utf-8"?>
<OutputDocType1 xmlns="http://MadeupNS1">
   <Description xmlns="">Hello I'm the source description</Description>
   <Description xmlns="">Hello I'm the source description 2</Description>
   <Title>Hello I'm the title</Title>
</OutputDocType1>

这就是问题所在。在描述行我得到一个 xmlns=""

有人知道如何解决这个问题吗?

谢谢

戴夫

【问题讨论】:

    标签: xslt namespaces xml-namespaces


    【解决方案1】:

    您的第一个 xslt 包含文字结果元素 Description 没有默认命名空间。因此,该元素不在命名空间中,而是通过xmlns="" 显式呈现。

    Namespaces in XML 1.0 第 6.2 节说:

    默认值中的属性值 命名空间声明可能为空。 这具有相同的效果,在 声明的范围,那里 没有默认命名空间。

    为了控制包含的样式表中生成的命名空间,您需要使用变量或参数将 namespace-uri 传递给其模板。

    <!-- in the included stylesheet -->
    <xsl:template match="Description[. != '']">
        <xsl:element name="Description" namespace="{$output-namespace}">
            <xsl:value-of select="."/>
        </xsl:element>
    </xsl:template>
    
    <!--
        and add this to your First Document Transformation stylesheet
        as a top level element under xsl:stylesheet
    -->
    <xsl:variable name="output-namespace" select="'http://MadeupNS1'"/>
    

    【讨论】:

    • 你能解释一下如何使用变量来完成吗?我自己也试过了,但是调用模板无法更新变量名。
    猜你喜欢
    • 2012-07-06
    • 2018-08-25
    • 1970-01-01
    • 2013-10-26
    • 1970-01-01
    • 2012-05-30
    • 1970-01-01
    • 2016-05-12
    • 1970-01-01
    相关资源
    最近更新 更多