Pergunta

Eu vi esse recurso Texto do link mas ainda tenho problemas para gerar um documento XHTML válido usando o analisador MSXML.

Tenho como entrada o seguinte documento:

    <?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>

onde os desagradáveis ​​​​xmlns="" são produzidos porque inseri a instrução:

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

ao criar o documento de entrada antes da transformação.

O XSLT importa a transformação que uso para capturar os elementos 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"/>

e dentro de _standard.xsl tenho o código que faz a transformação relevante:

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

Ainda não tenho os xmlns necessários na marcação html:

<html xml:lang="it">

E ainda tenho os xmlns desagradáveis ​​intercalados no código HTML:

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

Onde estou errando?

Observe:DEVO usar um modelo pull para transformação, não posso usar uma transformação de identidade

Foi útil?

Solução

Com o modelo DOM (MSXML usa) o namespace de um elemento ou nó de atributo é determinado quando ele é criado, você não pode alterá-lo posteriormente e tentativas como a sua de alterar namespaces definindo um atributo com o nome "xmlns" não alteram o namespace de nós.

Portanto, parece que você tem um documento de entrada com elementos sem namespace e deseja usar XSLT para transformá-lo em um documento com elementos no namespace XHTML.Nesse caso, você não pode usar xsl:copy, pois dessa forma você obtém elementos de resultado em nenhum namespace.Em vez disso, você precisa, por exemplo.

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

ou, claro, como você deseja esse namespace para todos os elementos de resultado, você pode colocar xmlns="http://www.w3.org/1999/xhtml" no elemento xsl:stylesheet da folha de estilo ou módulo(s) de folha de estilo que você deseja para criar elementos XHTML.

Outras dicas

Se você colocar xmlns="http://www.w3.org/1999/xhtml" no elemento 'html', ele se aplicará a esse elemento e a todos os seus elementos descendentes (não qualificados).O elemento 'body' está em um modelo completamente diferente, então você também precisa colocar uma declaração de namespace no elemento body ou, como já sugerido, basta colocar xmlns="http://www.w3.org/1999/xhtml " em todos os elementos xsl:stylesheet dos seus módulos de folha de estilo que devem criar elementos XHTML.

E também não fazer isso ou criar uma cópia do nó de entrada.Como seus elementos de entrada não estão em nenhum espaço para nome, se você copiar qualquer um deles, a cópia no resultado também não estará em nenhum espaço para nome, enquanto você deseja que os elementos de resultado estejam no espaço para nome XHTML.Portanto, fazer xsl:copy ou xsl:copy-of não funcionará para o que você deseja; em vez disso, você precisará executar seus elementos por meio de um modelo que altere o namespace, por exemplo.

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

@Martinho:Estou postando amostras.Desculpe ter sido genérico em meu comentário.

Documento de entrada (mínimo)

    <?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>

Depois o XSL principal apenas para conteúdo:

<?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>

Então _standard.xsl.Observe a instrução:

<xsl:template match="html">

é usado temporariamente, o xsl-copy foi usado como no primeiro trecho de código postado

    <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>

Eu encontrei na marcação de saída assim:

<body xmlns="">

A esperança é clara.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top