Шаблон xsl: include без пространства имен по умолчанию вызывает xmlns = "" - PullRequest
1 голос
/ 06 апреля 2010

У меня проблема с xsl: include и пространствами имен по умолчанию, в результате чего в конечном xml-документе содержатся узлы с xmlns = ""

В этом сценарии у меня есть 1 исходный документ, который представляет собой Plain Old 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>

Я хочу иметь возможность повторно использовать шаблон для описаний в обоих преобразованиях. Поскольку это одинаковая логика для обоих типов документов. Для этого я создал файл шаблона, который был xsl: include d в двух других преобразованиях:

<?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 = ""

Кто-нибудь знает, как решить эту проблему?

Спасибо

Dave

1 Ответ

3 голосов
/ 06 апреля 2010

Ваш первый xslt, который содержит буквальный элемент результата Description, не имеет пространства имен по умолчанию.Поэтому этот элемент не находится в пространстве имен и явно отображается как таковой через xmlns="".

Раздел 6.2 из Пространства имен в XML 1.0 говорит, что:

Значение атрибута в объявлении пространства имен по умолчанию МОЖЕТ быть пустым.Это имеет тот же эффект в рамках объявления, что отсутствует пространство имен по умолчанию.

Чтобы управлять пространством имен, сгенерированным во включенной таблице стилей, вам нужно будет передать 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'"/>
...