代码之家  ›  专栏  ›  技术社区  ›  Jonas

显式脚本结束标记始终转换为自动关闭

  •  10
  • Jonas  · 技术社区  · 17 年前

    <?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" /> 这会起作用,但似乎不起作用?

    11 回复  |  直到 17 年前
        1
  •  7
  •   Chris Chilvers    17 年前

    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();
    
        2
  •  4
  •   Dominic Cronin    17 年前

    从XSLT生成HTML时,这是一个非常常见的问题。我怀疑问题的根源在于XSLT本身是一个XML文档。即使您以序列化XML的形式开始XSLT程序,但当XSLT处理器获得它时,它已经反序列化为“infoset”表示形式。在XML级别,空标记和自关闭标记是等价的;元素完全没有子元素。这意味着您的XSLT处理器可能永远不会看到脚本元素同时具有开始和结束标记的程序版本。

    我通常通过使用一个合适的不间断空间来绕过这个问题。在任何情况下,都必须在script标记中添加一些内容。

    顺便说一下,这不是为了让IE开心。如果你看 HTML spec ,您会发现end标记是必需的。我相信有些人会觉得IE正确地实现它很讽刺。:-)

        3
  •  3
  •   Fritz W    15 年前

    我在MSDN论坛网站上找到了这个答案:

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

    如果在xsl文件结尾之前添加上述xslt代码,则会强制元素具有一些内容(本例中为空格),而不是自动关闭。试过了,成功了。

    这就是它所创造的:

    <script...> </script>
    

    而不是

    <script ... />.
    
        4
  •  1
  •   Diadistis    16 年前

    这是经过设计的,我所知道的唯一解决方法是使用自定义 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();
            }
        }
    }
    
        5
  •  1
  •   BizNuge    15 年前

    我也有这个问题[ javax.xml.transform.Transformer

    <textarea></textarea>

    节点的最终输出作为以下内容带入我的jsp:-

    <textarea/>
    

    这显然是把下面的代码搞砸了,因为它被视为textarea元素的更多内容。

    t.setOutputProperty(javax.xml.transform.OutputKeys.METHOD, "html"); 似乎提供了我预期的自动关闭行为。根据我自己的测试,这个属性默认为“xml”,因此显然,下面没有节点的xml标记就像自动关闭一样,是完美的。

    希望这能有所帮助。

        6
  •  1
  •   Sujit    15 年前

    <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/>
    
        7
  •  0
  •   annakata    17 年前

    当然,这是针对MS的XSLT引擎的?真奇怪。我不能说我在.NET1.1或2.0中遇到过这种情况,我有许多转换在做完全相同的事情,所以我建议您使用简单的解决方法。

        8
  •  0
  •   bluish dmajkic    15 年前

    对于那些使用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标准中规定的允许自动关闭的例外情况(即“区域”、“基础”、“基本字体”、“br”、“col”、“框架”、“hr”、“img”、“输入”、“链接”、“元”、“参数”)。至少对我来说是这样,现在网页在IE中也呈现得很好。

    http://bvandelft.ruhosting.nl/ToStream.java

        9
  •  0
  •   Kapil    14 年前

    我在脚本结束标记之前使用了一个注释来处理这个问题。

        10
  •  0
  •   David L.    12 年前

    <xsl:text disable-output-escaping="yes">
        &lt;script src="jquery-2.0.3.js"&gt;&lt;/script&gt;
    </xsl:text>
    

    顺便说一句,我认为method=“html”也应该做到这一点,但您不会像那样呈现xhtml,例如br不会被关闭。

        11
  •  0
  •   StevenP    11 年前

    另一个快速攻击是在标记中添加Javascript注释:

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">//</script>
    

    这只会在脚本的末尾添加一条注释-不过要小心,不要错误地注释掉任何内容!