簡體   English   中英

顯式腳本結束標記始終轉換為自動關閉

[英]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">
    &lt;script src="jquery-2.0.3.js"&gt;&lt;/script&gt;
</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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM