Как избавиться от некорректных атрибутов xmlns в HTML, преобразованных с помощью XSLT - PullRequest
2 голосов
/ 22 июля 2011

Я пытаюсь преобразовать документ .html, используя xslt. Сгенерированный html по какой-то причине имеет дополнительный атрибут xmlns в элементе head и пустой атрибут xmlns в элементе title.

example.html:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head><title>foo</title></head>
  <body><h1>bar</h1><img src="baz.jpg" /></body>
</html>

template.xsl:

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

  <xsl:output doctype-system="about:legacy-compat" method="html"
     omit-xml-declaration="yes" />

  <xsl:template match="/html/head">
    <head>
      <meta name="description" content="something added to the head element"/>
      <xsl:apply-templates select="./@*|./node()" />
    </head>
  </xsl:template>

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

</xsl:stylesheet>

Я тестировал преобразование с помощью xsltproc и php.

Запуск xsltproc:

$ xsltproc -html template.xsl example.html 
<!DOCTYPE html SYSTEM "about:legacy-compat">
<html xmlns="http://www.w3.org/1999/xhtml">
<head xmlns="http://www.w3.org/1999/xhtml"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="description" content="something added to the head element"></meta><title xmlns="">foo</title></head><body>
<h1>bar</h1>
<img src="baz.jpg">
</body>
</html>

Использование PHP:

<?php

$xmldoc = new DomDocument ();
$xmldoc->loadHTMLFile ("example.html");

$xsldoc = new DomDocument ();
$xsldoc->load ("template.xsl");

$xslt = new XSLTProcessor();
$xslt->importStylesheet($xsldoc);

echo $xslt->transformToXML ($xmldoc);

Я ожидаю, что все элементы в исходном документе будут находиться в пространстве имен html, поэтому я не понимаю, почему apply-templates, по-видимому, удаляет пространство имен из элемента title. Я также не понимаю, почему пространство имен html добавляется к элементу head.

Ответы [ 3 ]

2 голосов
/ 22 июля 2011

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

<xsl:template match="@*|node()[not(self::*)]">
  <xsl:copy/>
 </xsl:template>

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

Очевидно, что обязательно удалите эту строку из вашего XSLT:

xmlns="http://www.w3.org/1999/xhtml"

Ваш окончательный шаблон:

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

    <xsl:output doctype-system="about:legacy-compat" method="html"
        omit-xml-declaration="yes" />

    <xsl:template match="/html/head">
        <head>
            <meta name="description" content="something added to the head element"/>
            <xsl:apply-templates select="./@*|./node()" />
        </head>
    </xsl:template>

    <xsl:template match="@*|node()[not(self::*)]">
        <xsl:copy/>
    </xsl:template>

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

</xsl:stylesheet>
1 голос
/ 22 июля 2011

Пространство имен http://www.w3.org/1999/xhtml предназначено для XHTML. Поэтому вы должны установить режим вывода на xml вместо html, а также вывести правильный тип документа для XHTML или вместо этого отобразить как html и вообще не использовать пространство имен.

Обратите внимание, что XSLT не совсем подходит для генерации HTML5, но он идеально подходит для генерации HTML 4 или XHTML, если вы уделяете некоторое внимание деталям (например, какие элементы должны или не должны быть пустыми и т. Д.).

0 голосов
/ 22 июля 2011

Я не могу объяснить или воспроизвести ваши результаты.

Во-первых, ваш шаблон с match = "/ html / head" не должен совпадать с чем-либо во входном документе, поскольку ваши элементы / html / head находятся в пространстве имен.

С выходом SaxonЯ получаю вот что, что я считаю правильным:

<!DOCTYPE html
  SYSTEM "about:legacy-compat">
<html xmlns="http://www.w3.org/1999/xhtml">  
   <head>
      <title>foo</title>
   </head>   
   <body>
      <h1>bar</h1><img src="baz.jpg"></img></body>  
</html>

Так что вы либо делаете что-то отличное от того, что говорите (например, используете другую таблицу стилей или другой исходный документ из показанного) илиесть ошибка в используемом вами процессоре XSLT.

...