Как я могу предотвратить появление этих избыточных пространств имен из таблицы стилей XSLT?

При использовании таблицы стилей XSLT для преобразования XML-файла, содержащего встроенный XHTML (с использованием пространств имен), в чистый XHTML, у меня остаются избыточные определения пространств имен для элементов, которые изначально были XHTML. Простой тестовый пример:

XML:

<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet type="text/xml" href="fbb.xsl"?>
<foo xmlns="urn:foo:bar:baz" xmlns:html="http://www.w3.org/1999/xhtml">
    <bar>
        <baz>Some <html:i>example</html:i> text.</baz>
    </bar>
</foo>

XSL:

<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0" xmlns="http://www.w3.org/1999/xhtml" xmlns:fbb="urn:foo:bar:baz" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" exclude-result-prefixes="fbb">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/fbb:foo">
        <html>
            <head>
                <title>Example</title>
            </head>

            <body>
                <p>
                    <xsl:copy-of select="fbb:bar/fbb:baz/node()"/>
                </p>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

Вывод:

<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Example</title>
  </head>
  <body>
    <p>Some <html:i xmlns="urn:foo:bar:baz" xmlns:html="http://www.w3.org/1999/xhtml">example</html:i> text.</p>
  </body>
</html>

Можно ли предотвратить добавление избыточных пространств имен (и префикса) к элементу <i>? (Для справки, я использую xsltproc с libxml2-2.7.3 и libxslt-1.1.24 на Cygwin.)


person Ben Blank    schedule 06.05.2009    source источник


Ответы (2)


Вместо xsl:copy-of используйте шаблоны преобразования идентичности и удалите префикс пространства имен из элементов XHTML.

<xsl:stylesheet version="1.0"
                xmlns="http://www.w3.org/1999/xhtml"
                xmlns:fbb="urn:foo:bar:baz"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:html="http://www.w3.org/1999/xhtml"
                exclude-result-prefixes="fbb html">

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

  <xsl:template match="/fbb:foo">
    <html>
      <head>
        <title>Example</title>
      </head>
      <body>
        <p>
          <xsl:apply-templates select="fbb:bar/fbb:baz/node()"/>
        </p>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="html:*">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="@* | node()"/>
    </xsl:element>
  </xsl:template>

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

</xsl:stylesheet>
person jelovirt    schedule 06.05.2009

Обновите свой exclude-result-prefixes, включив в него пространство имен по умолчанию:

exclude-result-prefixes="#default"

Или вы можете подавить все встроенные пространства имен, выполнив:

exclude-result-prefixes="#all"

Однако есть некоторая нестабильность, поскольку некоторые процессоры ожидают список, разделенный пробелами, в то время как другие ожидают список, разделенный запятыми. xsltproc, похоже, любит разделение запятыми, поэтому, если вы все еще хотите быть явным, вы можете сделать:

exclude-result-prefixes="#default,fbb"
person johnvey    schedule 06.05.2009
comment
Хм… моя копия xsltproc фактически выдает ошибку неопределенного пространства имен для списков, разделенных запятыми. Список, разделенный пробелами, включая #default, похоже, не меняет своего поведения, а включение #all снова создает неопределенное пространство имен. - person Ben Blank; 06.05.2009
comment
libxslt поддерживает только XSLT 1.0, а #default и #all - XSLT 2.0. - person jelovirt; 06.05.2009