2009-05-20 3 views
22

Sto usando xslt per trasformare un file xml in html. Il motore .net xslt continua a servire tag autochiudenti per tag vuoti.Numero di tag auto-chiusura XSLT

Esempio:

<div class="test"></div> 

diventa

<div class="test" /> 

Il primo è valido html, mentre il secondo è html illegale e rende male. La mia domanda è: Come faccio a dire al motore xslt (XslCompiledTransform) di non usare tag auto-chiudenti.

Se non è possibile, come posso dire al mio browser (IE6 + in questo caso) di interpretare correttamente i tag a chiusura automatica.

+0

In questo articolo mi ha aiutato a capire il problema http://webkit.org/blog/68/understanding-html-xml-and-xhtml/ – Ryan

risposta

11

Se si utilizza XmlWriter come ouput st ream, usa invece HTMLTextWriter. XMLWriter riformatta nuovamente l'output HTML in XML.

+0

il problema è che TextWriter è astratto –

+1

Ok, ho appena trovato HtmlTextWriter (da ASP.net - System.Web.UI) .Penso che tenga la soluzione. TY. –

+0

il semplice I trovato stava creando una nuova classe XmlTextWriter e sovrascrive il metodo WriteEndElement, segue la risposta completa https://stackoverflow.com/a/48896012/540063 – gblmarquez

21

Modificare il metodo xsl:output in html (anziché in xml).

o aggiungerlo, se non l'hai già ottenuto l'elemento

<xsl:output method="html"/> 
+2

E dose non sembra funzionare. Ho provato varie combinazioni di ma continua a darmi xml. –

+0

Avete due voci per caso? Non sto usando .NET, ma Xalan in Java permette che lo –

+0

No, non è il mio caso. –

2

Non si può dire al vostro browser per gestire HTML non valido come HTML - sei fortunato si capisce HTML malformato a tutti. :)

sicuramente fare questo nel vostro foglio di stile:

<xsl:output method="html"/> 

Ma, se il documento di origine ha spazi dei nomi, questo non fare il trucco. I processori XSLT sembrano cambiare silenziosamente il metodo di output in XML se i nodi dello spazio dei nomi sono presenti nell'output.

È necessario sostituire tutte le istanze di <xsl:copy-of> e <xsl:copy> con creazioni di elementi con solo il nome locale, ad es.

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

Vedi

ecc

+0

Ho solo lo spazio dei nomi predefinito: xmlns: xsl = "http://www.w3.org/1999/XSL/Transform Come hai detto, penso che ritorni a xml. –

+0

Intendevo lo spazio dei nomi nei tuoi dati di origine documento, non il documento XSLT –

+0

Ah ok, mi dispiace, non uso lo spazio dei nomi nel documento soruce Penso che sia il fatto che io uso un XmlTextWriter che impone il "comportamento xml". Comunque, grazie mille per il vostro aiuto e per il tuo tempo –

2

Per me è stato un problema nel sceneggiatura tag.Ho risolto riempiendo con una virgola (;)

<script type="text/javascript" src="somewhere.js">;</script> 
2

mettevo un elemento <xsl:text> dentro, come:

<script type="text/javascript" src="/scripts/jquery.js"><xsl:text> </xsl:text></script> 
14

Una soluzione può essere quella di inserire un elemento commento per forzare generazione di chiusura non sé:

<script type="text/javascript" src="nowhere.js"> 
<xsl:comment></xsl:comment> 
</script> 

non è una bella soloution, ma funziona :-)

0.123.

/Sten

+1

Questa soluzione è perfetta per me. Grazie – boothinator

+1

Piuttosto come mia mamma! Grazie per quello! – maryisdead

0

Ho appena sperimentato lo stesso problema con XSL di PHP 5, con output/@ method = html. Sembra che l'assegnazione di un attributo valore vuoto causerà elementi da emettere come validi non auto-chiusura, tag non chiusi:

<input type="text" name="foo" value="{my-empty-value}" /> 

conseguenza:

<input type="text" name="foo" value=""> 

Una possibile soluzione è quella di aggiungere condizionale l'attributo:

<xsl:if test="string-length(my-empty-value) > 0"> 
    <xsl:attribute name="value"> 
     <xsl:value-of select="my-empty-value" /> 
    </xsl:attribute> 
</xsl:if> 

conseguente:

<input type="text" name="foo" /> 
+1

Sembra che tu stia rispondendo a una domanda diversa: come ottenere un tag che si chiude automaticamente anziché un tag non chiuso. L'OP chiede come ottenere un tag chiuso, non autochiudente anziché un tag a chiusura automatica. Ho ragione? – LarsH

1

Ci sono alcune cose che dovete stare attenti:

  1. Nel vostro uso xsl < xsl: metodo di uscita = 'html'>
  2. set OutputSettings nel XmlWriter uscita
  3. in Html all'interno di xsl, non impostare gli attributi nel tag html come questo < html xmlns = "http://www.w3.org/1999/xhtml"> ma utilizzare < html invece.

Questo è un pezzo di codice di lavoro:

string xmlStr = "<?xml version='1.0' encoding='UTF-8'?><Data></Data>"; 
XmlDocument doc = new XmlDocument(); 
doc.LoadXml(xmlStr); 
string xslContents = @" 
<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' 
xmlns:msxsl='urn:schemas-microsoft-com:xslt' exclude-result-prefixes='msxsl'> 
<xsl:output method='html' version='4.0' omit-xml-declaration='yes' indent='yes'/> 
<xsl:template match='Data'> 
<html> 
<body> 
    <div></div> 
</body> 
</html> 
</xsl:template> 
</xsl:stylesheet>"; 
XslCompiledTransform xsl = new XslCompiledTransform(); 
xsl.Load(XmlReader.Create(new StringReader(xslContents))); 
StringWriter result = new StringWriter(); 
using (XmlWriter writer = XmlWriter.Create(result, xsl.OutputSettings)) 
{ 
    xsl.Transform(doc, null, writer); 
} 
System.Diagnostics.Debug.Write(result.ToString()); 
+0

L'utilizzo del metodo di output sul foglio di stile è stata l'unica soluzione che ha funzionato per me. Ho bisogno di trasformare un XML tramite un foglio di stile in HTML e non ho potuto usare l'oggetto XmlWriter, solo HtmlTextWriter che non ha le stesse impostazioni. Per farla breve, questo ha funzionato per me anche se non lo amo così tanto come se potessi farlo a livello di programmazione. –

0

Io uso il seguente ogni volta che desidero evitare che un elemento dalla chiusura automatica:

<xsl:value-of select="''" /> 

Questo inganna il motore di rendering in credi che ci sia contenuto all'interno dell'elemento, e quindi impedisce l'auto-chiusura.

E 'un po' di un brutto correzione quindi vi consiglio che lo contiene in un modello descrittivo e chiamando che ogni volta invece:

<xsl:template name="PreventSelfClosure"> 
    <xsl:value-of select="''" /> 
</xsl:template> 


<div class="test"> 
    <xsl:call-template name="PreventSelfClosure"/> 
</div> 

Questo sarà quindi rendere la seguente:

<div class="test"></div> 

http://curtistimson.co.uk/post/xslt/how-to-prevent-self-closing-elements-in-xslt/

0

Il modo semplice che ho trovato è stato creare una nuova classe XmlTextWriter per sovrascrivere il metodo WriteEndElement, forzare il tag non di chiusura e passare il processo di serializzazione come parametro.

public class MyXmlTextWriter : XmlTextWriter 
{ 
    public MyXmlTextWriter(Stream stream) : base(stream, Encoding.UTF8) 
    { } 
    public MyXmlTextWriter(TextWriter stream) : base(stream) 
    { } 

    public override void WriteEndElement() 
    { 
     base.WriteFullEndElement(); 
    } 
}