[英]Explicit script end tag always converted to self-closing
我正在使用xslt將xml轉換為aspx文件。 在xslt中,我有一個腳本標記包含一個jquery.js文件。 要使其與IE一起使用,腳本標記必須具有明確的結束標記。 出於某種原因,這不適用於下面的xslt。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
xmlns:asp="remove">
<xsl:output method="html"/>
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>TEST</title>
<script type="text/javascript" src="jquery-1.2.6.js"></script>
但是,如果我更改腳本標記,如下所示,它的工作原理。
<script type="text/javascript" src="jquery-1.2.6.js">
// <![CDATA[ // ]]>
</script>
我認為<xsl:output method="html" />
可以解決問題,但它似乎不起作用?
/喬納斯
如果您自己創建XmlWriter,則需要將transform的OutputSettings傳遞給XmlWriter,例如:
XmlDocument doc = new XmlDocument();
doc.LoadXml("<book><author>Trudi Canavan</author><title>Voice of the Gods</title></book>");
XslCompiledTransform transform = new XslCompiledTransform();
transform.Load("XSLTFile1.xslt");
StringBuilder output = new StringBuilder();
// Here we pass the output setting to the writer, otherwise the transform
// may be set to Html, but the XmlWriter will be outputting Xml
XmlWriter writer = XmlWriter.Create(output, transform.OutputSettings);
transform.Transform(doc, writer);
Console.WriteLine(output.ToString());
Console.ReadKey();
從XSLT生成HTML時,這是一個非常常見的問題。 我懷疑問題的根源是XSLT本身是一個XML文檔。 即使您將XSLT程序作為序列化XML開始,到XSLT處理器獲取它時,它已經被反序列化為“信息集”表示。 在XML級別,空標簽和自封閉標簽是等效的; 元素很簡單,沒有孩子。 這意味着您的XSLT處理器可能永遠不會看到腳本元素具有開始和結束標記的程序版本。
我通常使用一個適當逃脫的不間斷空間來繞過這個。 無論如何,你必須在script標簽中放置一些內容。
順便說一下 - 這不是讓IE快樂。 如果查看HTML規范 ,您會發現需要結束標記。 我相信有些人會覺得IE正確實現它具有諷刺意味。 :-)
我在MSDN論壇網站上找到了這個答案:
<xsl:value-of select="' '"/>
如果你在xsl文件的末尾之前添加上面的xslt代碼,它會強制元素有一些內容(在這種情況下是空格)而不是自我關閉本身。 嘗試過,它有效。
這就是它創造的:
<script...> </script>
代替
<script ... />.
這是設計的,我知道的唯一解決方法是使用自定義XmlTextWriter
:
public class HtmlTextWriter : XmlTextWriter
{
private readonly string[] fullEndElements =
new string[] { "script", "title" };
private string lastStartElement = null;
public HtmlTextWriter(TextWriter textWriter)
: base(textWriter)
{
}
public HtmlTextWriter(string filename, Encoding encoding)
: base(filename, encoding)
{
}
public HtmlTextWriter(Stream w, Encoding encoding)
: base(stream, encoding)
{
}
public override void WriteStartElement(string prefix, string localName, string ns)
{
lastStartElement = localName;
base.WriteStartElement(prefix, localName, ns);
}
public override void WriteEndElement()
{
if (Array.IndexOf(fullEndElements, lastStartElement) > -1)
{
base.WriteFullEndElement();
}
else
{
base.WriteEndElement();
}
}
}
Bart van Delfts的回答讓我指出了正確的方向,為這個暗示歡呼!
我使用[ javax.xml.transform.Transformer ]也遇到了這個問題每當我試圖解析格式化的html片段時,在我的情況下: -
<textarea></textarea>
來自Node的最終輸出被帶入我的jsp中: -
<textarea/>
這顯然搞砸了以下任何代碼,因為它被視為textarea元素的更多內容。
設置t.setOutputProperty(javax.xml.transform.OutputKeys.METHOD, "html");
似乎提供了我所期望的自我關閉行為。 這個屬性在我自己的測試中默認為“xml”,所以很明顯,在它下面沒有節點的xml標簽非常適合自我關閉。
希望無論如何都有幫助。
考慮這個例子,
<Discount>
<!--<xsl:if test="Discount>0">-->
<xsl:value-of select="Discount"/>
<!--</xsl:if>-->
</Discount>
如果我正在為產品打折。 我在使用前檢查它。 它將返回輸出,
<Discount>value of the discount</Discount>
但是,如果我不贊同上述例子,
<Discount>
<xsl:if test="Discount>0">
<xsl:value-of select="Discount"/>
</xsl:if>
</Discount>
它將在xslt之后返回o / p(如果折扣> 0),
<Discount/>
如上所述,有一些技巧可以將不可見的內容放入元素中,但在xslt中,您始終可以將精確的輸出呈現為文本:
<xsl:text disable-output-escaping="yes">
<script src="jquery-2.0.3.js"></script>
</xsl:text>
順便說一句。 我認為method =“html”也可以做到這一點,但你不會像那樣渲染xhtml,例如br不會被關閉。
我在腳本結束標記之前使用了注釋來解決此問題。
另一個快速黑客是在標記中添加Javascript注釋:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">//</script>
這只會在腳本的末尾添加注釋 - 但要注意不要錯誤地評論任何內容!
對於那些使用Xalan 2.7.0(Java)的人,我遇到了同樣的問題。 我在原始源代碼中采用了org / apache / xml / serializer / ToStream.java文件來解決這個問題。 如果指定為outputProperty:
private static Properties XHTML() {
Properties p = new Properties();
p.setProperty(OutputKeys.METHOD, "xhtml");
p.setProperty(OutputKeys.DOCTYPE_PUBLIC,
"-//W3C//DTD XHTML 1.0 Strict//EN");
p.setProperty(OutputKeys.DOCTYPE_SYSTEM,
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd");
p.setProperty(OutputKeys.ENCODING, "UTF-8");
p.setProperty("{http://xml.apache.org/xalan}indent-amount", "4");
p.setProperty(OutputKeys.INDENT, "yes");
p.setProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
p.setProperty("{http://example.com}selfclosing","no");
return p;
}
注意selfclosing
的最后一行。 這是在此更新版本的ToStream.java中響應的屬性,它將阻止<div />
和<script />
標記以及輸出<div></div>
和<script></script>
標記。 它還包括這些例外,即HTML標准中指定的允許自動關閉的(例如“area”,“base”,“basefont”,“br”,“col”,“frame”,“hr”) “,”img“,”輸入“,”鏈接“,”元“,”參數“)。 它至少對我有用,現在網頁在IE中也很好用。
新的ToStream.java文件可以在http://bvandelft.ruhosting.nl/ToStream.java找到,並且serializer.jar的預編譯版本(使用2.7)也可以在同一個URL上使用,但是serializer.jar (其中包含ToStream的編譯版本)不允許發布1個URL :-p
這當然是針對MS的XSLT引擎的嗎? 多么奇怪。 我不能說我在.NET 1.1或2.0中遇到過這種情況,並且我有很多變換做同樣的事情,所以我建議你選擇簡單的解決方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.