2009-05-20 7 views
22

Ich verwende Xslt, um eine XML-Datei in HTML zu transformieren. Die .net xslt-Engine liefert mir selbstschließende Tags für leere Tags.XSLT selbstschließende Tags Ausgabe

Beispiel:

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

wird

<div class="test" /> 

Erstere gilt, html, während letztere illegal HTML ist und rendert schlecht. Meine Frage ist: Wie erkläre ich die Xslt-Engine (XslCompiledTransform), um nicht selbstschließende Tags zu verwenden.

Wenn es nicht möglich ist, wie kann ich meinem Browser (IE6 + in diesem Fall) sagen, selbstschließende Tags korrekt zu interpretieren.

+0

Dieser Artikel hat mir wirklich geholfen http://webkit.org/blog/68/understanding-html-xml-and-xhtml/ – Ryan

Antwort

11

Wenn Sie XmlWriter als ouput verwenden st Verwenden Sie stattdessen HTMLTextWriter. XMLWriter formatiert Ihre HTML-Ausgabe zurück in XML.

+0

das Problem ist, dass TextWriter abstrakt ist. –

+1

Ok, ich gerade über HtmlTextWriter gefunden (von ASP.net - System.Web.UI). Ich denke, dass es die Lösung enthält. TY. –

+0

die einfache ich Gefunden wurde eine neue XmlTextWriter-Klasse erstellen und überschreiben die Methode WriteEndElement, folgt die vollständige Antwort https://stackoverflow.com/a/48896012/540063 – gblmarquez

21

Ändern Sie Ihre xsl:output-Methode zu html (anstelle von xml).

Oder es hinzufügen, wenn Sie nicht bereits haben

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

Es dosen't zu funktionieren scheint, das Problem zu verstehen. Ich habe verschiedene Kombinationen von ausprobiert, aber er gibt mir weiterhin xml. –

+0

Haben Sie zufällig zwei Einträge? Ich verwende nicht .NET, aber Xalan in Java erlaubt das –

+0

Nein, es ist nicht mein Fall. –

2

das Element bekam können Sie Ihren Browser nicht sagen ungültige HTML als HTML zu handhaben - Sie Glück haben, versteht es ungültige HTML überhaupt. :)

Auf jeden Fall tut dies in Ihrem Stylesheet:

<xsl:output method="html"/> 

Aber, wenn Ihr Quelldokument Namensraum hat, wird dies nicht den Trick. XSLT-Prozessoren scheinen die Ausgabemethode automatisch in XML zurückzusetzen, wenn Namespace-Knoten in der Ausgabe vorhanden sind.

Sie müssen alle Instanzen von <xsl:copy-of> und <xsl:copy> durch Kreationen von Elementen mit nur dem lokalen Namen ersetzen, z.

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

Siehe

usw.

+0

Ich habe nur den Standard-Namespace: xmlns: xsl = "http://www.w3.org/1999/XSL/Transform Wie Sie gesagt haben, ich glaube, er wechselt zurück zu xml. –

+0

Ich meinte den Namespace in Ihren Quelldaten Dokument, nicht das XSLT-Dokument –

+0

Ah ok, sorry, ich benutze keinen Namespace im soruce Dokument Ich denke es ist die Tatsache, dass ich einen XmlTextWriter benutze, der das "xml-Verhalten" erzwingt. Wie auch immer, ich danke Ihnen sehr Hilfe und für Ihre Zeit. –

2

Für mich ist es ein Problem in dem Skript Tag war.I löste es, indem sie es mit einem Semikolon (;) Befüllen

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

I verwendet, innerhalb eines <xsl:text> Element zu setzen, wie:

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

Eine Abhilfe kann ein Kommentar Element eingefügt zu zwingen Erzeugung von nicht selbstschließend:

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

es ist keine schöne soloution, aber es funktioniert :-)

/Sten

+1

Diese Lösung ist perfekt für mich. Danke – boothinator

+1

Ziemlich wie meine Mutter! Dank dafür! – maryisdead

0

Gerade das gleiche Problem mit PHP 5 XSL, mit Ausgabe/@ Methode = html. Es scheint, dass ein leeres Wert Attribut zuweisen verursacht Elemente Ausgabe als ungültig nicht-selbstschließenden, nicht geschlossene Tags sein:

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

Ergebnisse in:

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

Eine mögliche Lösung ist bedingt hinzufügen das Attribut:

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

ergibt:

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

Es scheint, dass Sie eine andere Frage beantworten: wie Sie ein selbstschließendes Tag anstelle eines nicht geschlossenen Tags erhalten. Das OP fragt, wie man ein geschlossenes, nicht selbstschließendes Tag anstelle eines sich selbst schließenden Tags erhält. Habe ich recht? – LarsH

1

Es gibt ein paar Dinge, die Sie müssen vorsichtig sein:

  1. In Ihrer xsl Verwendung < xsl: output method = 'html'>
  2. Satz Output in Ihrer Ausgabe XmlWriter
  3. im Html in Ihrem xsl, setzen Sie keine Attribute in HTML-Tag wie diese < html xmlns = "http://www.w3.org/1999/xhtml"> aber verwenden < html> stattdessen.

Dies ist ein Stück von Arbeitscode:

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

Die Verwendung der Ausgabemethode im Stylesheet war die einzige Lösung, die für mich funktionierte. Ich muss ein XML über ein Stylesheet in HTML umwandeln und konnte das XmlWriter-Objekt nicht verwenden, nur HtmlTextWriter, der nicht über die gleichen Einstellungen verfügt. Lange Rede kurzer Sinn, das funktionierte für mich, obwohl ich es nicht so sehr liebe, als könnte ich es programmatisch machen. –

0

ich folgendes verwenden, wenn ich ein Element aus selbstschließ verhindern wollen:

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

Dadurch wird die Rendering-Engine Narren in glaube, dass es Inhalt im Element gibt, und verhindert somit die Selbstschließung.

Es ist ein bisschen von einem hässlichen fix, damit ich es in einem beschreibenden Vorlage empfehlen enthalten und fordern, dass jedes Mal statt:

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

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

:

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


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

Dies wird die folgenden dann machen

0

Der einfache Weg, den ich gefunden habe, war das Erstellen einer neuen XmlTextWriter-Klasse, um die Methode WriteEndElement zu überschreiben, das nicht schließende Tag erzwingend und die Serialisierungsprozess als Parameter.

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

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