Вопрос по – XSL - копировать элементы, но удалять неиспользуемые пространства имен

18

У меня есть некоторый XML, который объявляет пространство имен, которое используется только для атрибутов, например:

<?xml version="1.0" encoding="UTF-8"?>
<a xmlns:x="http://tempuri.com">
    <b>
        <c x:att="true"/>
        <d>hello</d>
    </b>
</a>

Я хочу использовать XSL для создания копии выбранных узлов и их значений - избавления от атрибутов. Итак, мой желаемый результат:

<?xml version="1.0" encoding="UTF-8"?>
<b>
    <c />
    <d>hello</d>
</b>

У меня есть некоторый XSL, который почти делает это, но, похоже, я не могу его остановить, поместив объявление пространства имен в элемент верхнего уровня выходных данных. Мой XSL это:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="/">
        <xsl:apply-templates select="/a/b"/>
    </xsl:template>

    <xsl:template match="node()">
        <xsl:copy>
            <xsl:apply-templates select="node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Первый элемент вывода<b xmlns:x="http://tempuri.com"> вместо<b>, Я пытался объявить пространство имен в XSL и поместить префикс вexclude-result-prefixes список, но это, похоже, не имеет никакого эффекта. Что я делаю неправильно?

ОБНОВЛЕНИЕ: я обнаружил, что путем объявления пространства имен в XSL и использованияextension-element-prefixes Атрибут работает, но это не так! Я думаю, я мог бы использовать это, но я хотел бы знать, почемуexclude-result-prefixes не работает!

ОБНОВЛЕНИЕ: На самом деле, кажется, этоextension-element-prefixes Решение работает только со встроенным механизмом XSLT XMLSpy, а не с MSXML.

Ваш Ответ

4   ответа
2

Это удалит пространство имен x из вывода.

<xsl:namespace-alias result-prefix="#default" stylesheet-prefix="x" />

Не забудьте сделать две вещи, когда вы имеете дело с пространством имен по умолчанию. Сначала сопоставьте его с тегом таблицы стилей, а затем удалите его, используя псевдоним пространства имен.

9
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    xmlns:x="http://tempuri.com">
    <xsl:template match="/">
        <xsl:apply-templates select="/a/b"/>
    </xsl:template>

    <xsl:template match="*">
        <xsl:element name="{local-name(.)}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="@*">
        <xsl:copy/>
    </xsl:template>

    <!-- This empty template is not needed.
Neither is the xmlns declaration above:
    <xsl:template match="@x:*"/> -->
</xsl:stylesheet>

Я нашел объяснениеВот.

Michael Kay wrote:
exclude-result-prefixes only affects the namespaces copied from the stylesheet by a literal result element, it doesn't affect copying of namespaces from source documents.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded Graham Clark
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
4

Попробуйте это (обратите внимание на атрибутcopy-namespaces='no'):

<xsl:template match="node()">
    <xsl:copy copy-namespaces="no">
            <xsl:apply-templates select="node()"/>
    </xsl:copy>
</xsl:template>
5
<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:x="http://tempuri.com"
  exclude-result-prefixes="x"
>

  <!-- the identity template copies everything 1:1 -->
  <xsl:template match="@* | node()">
     <xsl:copy>
      <xsl:apply-templates select="@* | node()" />
    </xsl:copy>
  </xsl:template>

  <!-- this template explicitly cares for namespace'd attributes -->
  <xsl:template match="@x:*">
    <xsl:attribute name="{local-name()}">
      <xsl:value-of select="." />
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

Похожие вопросы