Как избавиться от атрибута xmlns =»» (без пространства имен) в выводе XSLT

#xml #xslt

#xml #xslt

Вопрос:

Вот мой (упрощенный для данного случая) XML:

 <?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="test_1.xsl" type="text/xsl"?>

<doc xmlns="http://www.foo.org">
  <div>
    <title>Mr. Title</title>
    <paragraph>This is one paragraph.
    </paragraph>
    <paragraph>Another paragraph.
    </paragraph>
  </div>
</doc>
  

И вот мой XSLT:

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

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

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

 <xsl:template match="foo:doc">
  <xsl:element name="newdoc" namespace="http://www/w3.org/1999/xhtml">
   <xsl:apply-templates/>
  </xsl:element>
 </xsl:template>

 <xsl:template match="foo:div">
  <segment title="{foo:title}">
   <xsl:apply-templates/>
  </segment>
 </xsl:template>

 <xsl:template match="foo:title">
  <xsl:element name="h2">
   <xsl:apply-templates/>
  </xsl:element>
 </xsl:template>

 <xsl:template match="foo:paragraph">
  <xsl:element name="p">
   <xsl:apply-templates/>
  </xsl:element>
 </xsl:template>

</xsl:stylesheet>
  

На выходе получается следующее:

 <newdoc xmlns="http://www/w3.org/1999/xhtml">
  <segment xmlns="" title="Mr. Title">
    <h2>Mr. Title</h2>
    <p>This is one paragraph.
    </p>
    <p>Another paragraph.
    </p>
  </segment>
</newdoc>
  

что замечательно, за исключением xmlns =»» в элементе segment, который, похоже, не определяет пространство имен для себя и всех своих дочерних элементов. Как я могу заставить его не добавлять это?

Примечание: Я также попытался преобразовать первый узел с

 <xsl:template match="mydoc:doc">
  <html xmlns="http://www/w3.org/1999/xhtml">
   <xsl:apply-templates/>
  </html>
 </xsl:template>
  

вместо этого, но это приводит к тому же эффекту.

Спасибо полезным людям!

Ответ №1:

Похоже, вы хотите поместить все элементы выходного документа в «http://www/w3.org/1999/xhtml «пространство имен. В настоящее время вы указываете пространство имен только для элемента «newdoc», все остальные элементы находятся в пространстве имен по умолчанию, поскольку в вашей таблице стилей нет объявления пространства имен. Вложение внутри таблицы стилей определяет, к какому пространству имен принадлежат элементы, а не вложение после преобразования.

Вы можете объявить пространство имен по умолчанию в своей таблице стилей, чтобы повлиять на все элементы, не отвечающие требованиям:

 <xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:foo="http://www.foo.org"
    xmlns="http://www.w3.org/1999/xhtml">
  

Теперь вам также больше не нужен xsl:element тег и вы можете напрямую использовать newdoc для создания элемента в правильном пространстве имен.

Комментарии:

1. У меня это тоже сработало, но в ответе есть опечатка. В ответе говорится, что http://www/w3.org ... в нем должно быть указано http://www.w3.org ... . Косая черта должна быть точкой.

Ответ №2:

В foo:div шаблоне вы создаете segment элемент с пустым пространством имен. Поскольку родительский элемент имеет другое пространство имен, процессор должен добавить это объявление пространства имен.

Если вам нужно segment то же пространство имен, что и родительское, тогда используйте xsl:element вместо:

 <xsl:template match="foo:div">
    <xsl:element name="segment">
        <xsl:attribute name="title">
            <xsl:value-of select="foo:title"/>
        </xsl:attribute>
        <xsl:apply-templates/>
    </xsl:element>
</xsl:template>