Преобразование XSLT для создания действительного XHTML: проблема с пространством имен

Я видел этот ресурс, текст ссылки, но у меня все еще есть проблемы с созданием действительного документа XHTML с помощью синтаксического анализатора MSXML.

У меня есть на входе следующий документ:

    <?xml version="1.0" encoding="UTF-8" ?> 
- <html xml:lang="it" xmlns="http://www.w3.org/1999/xhtml">
- <head xmlns="">
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
   <title>Bla bla bla</title> 
  <link rel="stylesheet" type="text/css" media="screen" href="css/bla.css" /> 
  </head>
- <body xmlns="" style="background-color:#DFDFDF;left-margin:0;margin-top:0">
    ....
    </body>
  </html>

где неприятные xmlns="" создаются, потому что я вставил инструкцию:

parserInstance.documentElement.setAttribute "xmlns", "http://www.w3.org/1999/xhtml"

при создании входного документа перед преобразованием.

XSLT импортирует преобразование, которое я использую для захвата html-элементов.

<xsl:stylesheet 
    version="1.0" 
    xmlns:xhtml="http://www.w3.org/1999/xhtml"
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    exclude-result-prefixes="xhtml xsl"
>
<xsl:import href="_lib.xsl"/>
<xsl:import href="_standard.xsl"/>

и в _standard.xsl у меня есть код, который выполняет соответствующее преобразование:

<xsl:template match="html">
<xsl:copy>
    <xsl:copy-of select="@*" />
    <xsl:apply-templates select="head" />       
    <xsl:apply-templates select="body" />       
</xsl:copy>

Тем не менее у меня нет необходимых xmlns в разметке html:

<html xml:lang="it">

И у меня все еще есть неприятные xmlns, перемежающиеся в html-коде:

<h1 xmlns="http://www.w3.org/1999/xhtml">BLA BLA</h1>

Где я ошибаюсь?

Пожалуйста, ОБРАТИТЕ ВНИМАНИЕ: я ДОЛЖЕН использовать модель извлечения для преобразования, я не могу использовать преобразование идентичности


person Daniel    schedule 09.03.2010    source источник


Ответы (3)


В модели DOM (используется MSXML) пространство имен элемента или узла атрибута определяется при его создании, вы не можете изменить его впоследствии, и попытки, подобные вашим, изменить пространства имен, установив атрибут с именем «xmlns», не изменяют пространство имен узлов.

Получается, что у вас есть входной документ с элементами без пространства имен и вы хотите использовать XSLT для преобразования его в документ с элементами в пространстве имен XHTML. В этом случае вы не можете использовать xsl:copy, так как таким образом вы получаете элементы результата без пространства имен. Вместо этого вам нужно, например.

<xsl:template match="html">
  <html xmlns="http://www.w3.org/1999/xhtml">
    ...
  </html>
</xsl:template>

или, конечно, если вам нужно это пространство имен для всех элементов результатов, вы можете поместить xmlns="http://www.w3.org/1999/xhtml" в элемент xsl:stylesheet таблицы стилей или модулей таблицы стилей, которые вы хотите для создания элементов XHTML.

person Martin Honnen    schedule 09.03.2010
comment
Выполнено, но атрибуты xmlns все еще присутствуют в некоторых элементах html в выходном документе. - person Daniel; 09.03.2010
comment
Разместите минимальные, но полные образцы вашего ввода XML и вашей таблицы стилей, которые позволят нам воспроизвести проблему, тогда я уверен, что мы сможем ее исправить. Я боюсь, что в некоторых элементах html все еще есть атрибуты xmlns, что не позволяет мне решить, откуда они происходят, соответственно, как это исправить, мне нужно увидеть код. - person Martin Honnen; 09.03.2010

Если вы поместите xmlns="http://www.w3.org/1999/xhtml" в элемент 'html', то он будет применяться к этому элементу и всем его (неквалифицированным) элементам-потомкам. Элемент body находится в совершенно другом шаблоне, поэтому вам либо нужно поместить объявление пространства имен в элемент body, либо, как уже предлагалось, просто указать xmlns="http://www.w3.org/1999/xhtml". " на всех элементах xsl:stylesheet ваших модулей таблицы стилей, которые должны создавать элементы XHTML.

А также не то, что делает или создаст копию входного узла. Поскольку ваши входные элементы не находятся в пространстве имен, если вы скопируете любой из них, копия в результате также не будет находиться в пространстве имен, в то время как вы хотите, чтобы элементы результата находились в пространстве имен XHTML. Таким образом, выполнение xsl:copy или xsl:copy-of не будет работать для того, что вы хотите, вместо этого вам нужно запустить свои элементы через шаблон, который изменяет пространство имен, например.

<xsl:template match=*">
  <xsl:element name="{local-name()}" namespace="http://www.w3.org/1999/xhtml">
    <xsl:apply-templates/>
  </xsl:element>
</xsl:template>
person Martin Honnen    schedule 10.03.2010

@Martin: я публикую образцы. Извините, что мой комментарий был общим.

Входной документ (минимальный)

    <?xml version="1.0" encoding="UTF-8"?>
<html xml:lang="it">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Page title</title>
<link rel="stylesheet" type="text/css" media="screen" href="css/stile.css"/>
</head>
<body>
<div id="errorPanel" class="errorPanel"/>
<navigation>

<panel name="navbar">
<link>
<url>resource1.htm</url>
<label>resource1</label>
</link>
</panel>

<panel name="special">
<link>
<url>resource2.htm</url>
<label>resource2</label>
</link>
</panel>
</navigation>

<content/>

<script type="text/javascript" src="lib/jquery.js"/>
<script type="text/javascript" src="backend.js"/>

</body>
</html>

Затем основной XSL только для контента:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns="http://www.w3.org/1999/xhtml" 
    exclude-result-prefixes="xsl"
>
<xsl:import href="_lib.xsl"/>
<xsl:import href="_standard.xsl"/>
<xsl:output 
    method="xml" 
    omit-xml-declaration="no" 
    encoding="UTF-8" 
    doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
/>

<xsl:template match="content">
            <h1>CONTENT</h1>
            <p>
                Bla bla bla
            </p>    
</xsl:template>
</xsl:stylesheet>

Затем _standard.xsl. Обратите внимание, инструкция:

<xsl:template match="html">

используется временно, xsl-копия использовалась как в первом размещенном фрагменте кода

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

<xsl:template match="html">
    <html xmlns="http://www.w3.org/1999/xhtml">
        <xsl:copy-of select="@*" />
        <xsl:apply-templates select="head" />       
        <xsl:apply-templates select="body" />       
    </html>
</xsl:template> 

<xsl:template match="head">
        <xsl:copy-of select="." />
</xsl:template> 

<xsl:template match="body">
    <body>
    <table id='toppanel'>
        <tr>
            <td>Bla bla bla</td>
            <td>Bla bla bla</td>
            <td>Bla bla bla</td>
        </tr>
    </table>

    <table>
    <tr>
        <xsl:apply-templates select="navigation/panel[@name='navbar']" mode="td"/>
    </tr>
    </table>

    <table>
    <tr>
        <td>
                <p>Area</p>
                <xsl:apply-templates select="navigation/panel[@name='special']" />
        </td>

        <td>
            <xsl:apply-templates select="content" />
        </td>

    </tr>
    </table>
    </body>
</xsl:template> 

</xsl:stylesheet>

Я нашел в выходной разметке следующее:

<body xmlns="">

Надежда ясна.

person Daniel    schedule 10.03.2010