【问题标题】:Transferring contents of HTML list to text将 HTML 列表的内容转换为文本
【发布时间】:2011-01-06 23:05:45
【问题描述】:

如何做到这一点? .InnerText 属性(在包含 div 元素上使用时)只给我 html。是否可以遍历所有包含的li 元素并提取它们的值?

【问题讨论】:

  • 这是 XHTML(格式良好的 XML 文档)吗?如果是,则存在一个优雅的解决方案。
  • @Dimitre Novatchev - 文档类型是 HTML 5,它是有效代码。
  • 这是一个很好的问题(来自我的 +1),我相信我的回答为您提供了比您问题的其他答案更好的选择。 :)
  • @Dimitre Novatchev - 确实是优雅的解决方案!谢谢。

标签: c# asp.net vb.net list xpath


【解决方案1】:

假设你有一个单独的变量列表(你已经提取了它),并且 /li 和下一个 li 之间没有任何内容:

string[] sep = {"</li>"};
foreach (string s in html.Replace("<li>","").Split(sep, StringSplitOptions.None)) 
//do something with s

用于测试的简单控制台应用程序:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string html = "<li>123</li><li>456</li>";
            string[] sep = {"</li>"};
            foreach (string s in html.Replace("<li>","").Split(sep, StringSplitOptions.None)) 
                Console.WriteLine(s);
            Console.ReadLine();
        }
    }
}

【讨论】:

  • 这会起作用,但它与 vlad 的解决方案存在相同的问题。尽管从技术上讲这不是处理它的最佳方法,但我最终可能会这样做。
【解决方案2】:

如果应该在服务器端完成,请使用HTML Agilitypack

var nodes = doc.SelectNodes("//ul[@id=\"myId\"]/li");
List<string> items = new List<string>();
foreach (var node in nodes)
    items.Add(node.InnerText);

更新

执行相同操作的 jquery 脚本(用于客户端):

<script type="text/javascript">
    function convertUlToText(ulID)
    {
        var text = '';
        $('#' + ulID + ' li').each(function() {
          text += $(this).html() + '\r\n';
        }
        return text;
    }
</script>

用法:

var textList = convertUlToText('myId');

【讨论】:

  • 非常有趣。如果使用 javascript 附加 ul,这会起作用吗?
  • @jgauffin - 即使做 element.InnerText 成功返回 html 内容?
  • 如果您需要客户端脚本,请查看我更新的示例。目前还不是很清楚你要做什么,因此很难给你一个正确的答案。
  • 对不起,正如我向 stephen776 解释的那样,这必须在服务器端完成。 +1 努力
  • 我回答的第一部分服务器端
【解决方案3】:

是否可以遍历所有 li 元素包含和提取 他们的价值观?

来自 OP 的评论

Doctype 为 HTML 5 且有效 代码。 – 拉杜

在这种情况下,只需使用以下 XPath 表达式

div//li//text()

这将选择作为所有 li 元素的后代的所有文本节点,这些元素是作为当前节点的子节点的任何 div 元素的后代。

使用 XPath 表达式来选择 XML 中的节点(HTML5 是格式良好的 XML)是推荐的、最直接和更可靠的方法,而不是难以构建、难以测试、难以理解和维护的规则表达式。

这是一个完整的代码示例

using System;
using System.Xml;

class TestXPath
{
    static void Main(string[] args)
    {
        string html5Text =
@"<html>
 <head>
 </head>
 <body>
  <div>
   <ul>
    <li>Line 1</li>
    <li>Line 2</li>
    <li>Line 3</li>
   </ul>
  </div>
 </body>
</html>";

        XmlDocument doc = new XmlDocument();
        doc.LoadXml(html5Text);

        string xpathExpr = @"/*/*/div//li//text()";

        XmlNodeList selection = doc.SelectNodes(xpathExpr);

        foreach (XmlNode node in selection)
        {
            Console.WriteLine(node.OuterXml);
        }

    }
}

执行上述应用程序时,会产生想要的正确结果

Line 1
Line 2
Line 3

【讨论】:

    【解决方案4】:

    你总是可以用一个简单的regEx“暴力破解”它,或者根据开始/结束标签分割字符串

    【讨论】:

    • 我已经习惯了从不使用正则表达式来解析 html,总是以泪水告终。
    • 尽管我倾向于同意 Radu 的观点,并为您的评论 +1,但我仍然倾向于使用 RegEx 来解析 HTML,并且花了很多时间哭泣...
    【解决方案5】:

    如果可能的话,我会使用 jQuery 循环遍历 UL 并返回每个 LI 的值。沿着这些思路......

    $('li').each(function () {
    
        alert($(this).html());
    
    });
    

    当然,如果您在服务器端需要这些值,则需要对页面方法或 Web 服务进行某种 ajax 调用。

    【讨论】:

    • 不幸的是不可能。我尝试过调用页面方法,但在我的情况下它不起作用,因为我需要使用一些在服务器端生成的标头。显然,如果我尝试通过称为 AJAX 传递它们,它们就会被忽略。
    • @Radu 用一个简单的 asmx Web 服务代替页面方法怎么样?
    • 我还没有尝试过,但你认为这可以让我传递特殊的标题吗?我正在尝试为动态生成的文件显示文件下载对话框,并将这些标题放在我的请求中:.AddHeader("Content-disposition", "attachment;filename=output.txt").AddHeader("Content-length", fileLength)。我认为 asmx 服务不会有帮助,因为我认为问题在于 AJAX 请求本身。
    • @Radu 我明白了...我不确定网络服务是否会有所帮助。有用于文件下载的 jQuery 插件...这是我发现的一个 filamentgroup.com/lab/… 可能会有所帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-27
    • 2012-06-21
    相关资源
    最近更新 更多