【问题标题】:Setting InnerHtml property using HtmlAgilityPack produces unexpected results使用 HtmlAgilityPack 设置 InnerHtml 属性会产生意外结果
【发布时间】:2016-04-26 18:14:11
【问题描述】:

我正在使用 HtmlAgilityPack 和 C# 来转换旧的 IE 标记以及 Javascript 以与其他浏览器兼容。这是一个例子:

旧代码:

<script for="thisForm" event="onsubmit()" language="JScript">

var Checked = false
var Counter = 0

for (;Counter < this.choice.length; Counter++)
{
    if (this.choice[Counter].checked)
    {
        Checked = true
        this.action = this.choice[Counter].value
    }
}

if (!Checked)
{
    alert ("Please make a selection")
    return false
}
</script>

我转换为:

<script ftype="text\JScript">
function thisForm_onsubmit(el)
{
var Checked = false
var Counter = 0

for (;Counter < el.choice.length; counter++)
{
    if (el.choice[counter].checked)
    {
        checked = true
        el.action = el.choice[counter].value
    }
}

if (!checked)
{
    alert ("please make a selection")
    return false
}
}
</script>

我在上面所做的是从脚本标签中删除了事件和语言属性,添加了 type="text/JScript" 属性并将 javascript 包装到函数代码中。

我通过简单地添加 HtmlNode 属性然后替换 InnerHtml 属性值来做到这一点。到目前为止,它对我来说很好,直到我遇到上述功能。不知何故,我没有给我上面的结果,而是得到以下结果:

<script type="text/JScript">
function thisForm_onsubmit(el)
{
var Checked = false
var Counter = 0

for (;Counter < el.choice.length; counter++)
{
    if (el.choice[counter].checked)
    {
        checked = true
        el.action = el.choice[counter].value
    }
}

if (!checked)
{
    alert ("please make a selection")
    return false
}

}
  el.choice.length;="" counter++)="" {="" if="" (el.choice[counter].checked)="" {="" checked="true" el.action="el.choice[Counter].value" }="" }="" if="" (!checked)="" {="" alert="" ("please="" make="" a="" selection")="" return="" false="" }="" }=""></ el.choice.length; counter++)
{
    if (el.choice[counter].checked)
    {
        checked = true
        el.action = el.choice[counter].value
    }
}

if (!checked)
{
    alert ("please make a selection")
    return false
}

}
></script>

我分配给 InnerHtml 的文本的奇怪部分是正确的,但 scriptNode.InnerHtml 显示不同的值

这是我的 C# 代码:

 if (scriptNode.Attributes["for"] != null)
 {
                                {
    if (scriptNode.Attributes["for"] != null)
                                        ctrl = scriptNode.Attributes["for"].Value;

                                    if (scriptNode.Attributes["event"] != null)
                                        evt = scriptNode.Attributes["event"].Value;

                                    if (scriptNode.Attributes["type"] != null)
                                        typ = scriptNode.Attributes["type"].Value;

                                    if (scriptNode.Attributes["language"] != null)
                                        lang = scriptNode.Attributes["language"].Value;
                                    if (scriptNode.InnerHtml != null)
                                        code = scriptNode.InnerHtml;

                                    func_name = ctrl + "_" + evt;
                                    if (ctrl != "window")
                                        new_script = Environment.NewLine + "function " + RemoveBrackets(func_name) + "(el)" + Environment.NewLine;
                                    else
                                        new_script = Environment.NewLine + "function " + AddBrackets(RemoveBrackets(func_name)) + Environment.NewLine;
                                    new_script += "{" + Environment.NewLine;


                new_script += "\r\n" + ReplaceThis(sFile, ctrl, evt, code, "this", "el") + "\r\n" + "}" + "\r\n";


                                    //remove for and event attributes
                                    scriptNode.Attributes["for"].Remove();
                                    scriptNode.Attributes["event"].Remove();

                                    //remove depraciated "language" attribute 
                                    //and replace it with "type" attribute
                                    if (scriptNode.Attributes["language"] != null)
                                        scriptNode.Attributes["language"].Remove();
                                    if (scriptNode.Attributes["type"] == null)
                                        scriptNode.Attributes.Add("type", "text/" + lang);

                                    //replace old javascript with a function code
                //HERE new_script variable contains the correct value but when I check  scriptNode.InnerHtml after assignment, it shows the messed up code.

                                    scriptNode.InnerHtml = new_script;

这很奇怪,我似乎找不到解决方案。

我尝试过使用 HtmlEncode

scriptNode.InnerHtml = HtmlDocument.HtmlEncode(new_script);

这产生了正确的脚本,如上面第二个示例中所述,但将所有 &amp;lt;&amp;gt; 替换为 &amp;lt;&amp;gt; 等。

所以结果是:

<script type="text/JScript">
function thisForm_onsubmit(el)
{

var Checked = false
var Counter = 0

for (;Counter &lt; el.choice.length; Counter++)
{
    if (el.choice[Counter].checked)
    {
        Checked = true
        el.action = el.choice[Counter].value
    }
}

if (!Checked)
{
    alert (&quot;Please make a selection&quot;)
    return false
}

}
</script>

我想用 InnerText 代替 InnerHtml,这更有意义,因为我要更改的不是真正的 HTML,而是 InnerText 属性是只读的。

谁能解释为什么会发生这种情况以及是否有解决方法?

【问题讨论】:

  • 您是否在使用多个线程,这些线程之间是否共享任何内容?看起来当多个线程都更新相同的值时会发生什么——你从一个线程中获得部分输出,并从另一个线程中获得部分输出。
  • 不,没有多个线程
  • 这很奇怪,因为到目前为止我已经为许多文件转换了 javascript 而没有问题,只是这个特定的文件给了我一个问题

标签: c# html-agility-pack


【解决方案1】:

修改后的脚本包含特殊字符&lt;,我真的怀疑这是导致问题的原因。 &lt; 很容易被误解为打开 HTML 标记的第一个字符,尤其是当它通过 InnerHtml 属性使用时。

这是一种可能的解决方法。假设new_script 是一个包含修改后的Javascript 的字符串变量,包括开始和结束标记(&lt;script type="text/JScript"&gt;&lt;/script&gt;)。您可以尝试将new_script 加载到新的HtmlDocument 中。然后替换 1st 中的旧脚本 HtmlDocument 使用来自第二个 HtmlDocument 实例的新脚本:

.....
var newDoc = new HtmlDocument();
newDoc.LoadHtml(new_script);
var newScript = newDoc.DocumentNode.SelectSingleNode("//script");
scriptNode.ParentNode.ReplaceChild(newScript, script);

dotnetfiddle demo

【讨论】:

  • 如何创建新节点? var newScript = newDoc.DocumentNode.SelectSingleNode("//script");只抓取第一个
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-30
  • 1970-01-01
  • 1970-01-01
  • 2023-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多