【问题标题】:Get only Xml among text file仅获取文本文件中的 Xml
【发布时间】:2016-10-16 01:50:25
【问题描述】:

我有许多文件“.txt”文件,文件中有通常的文本和 xml 标签。文件非常大,文件数量非常多。所以我只想拿没有文本的xml。我知道 标签从<body> 开始,以</body> 结束。我只需要<body><body> 中的所有嵌套标签

文件示例:

exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
 <body>
 ...
 </body>

exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText

exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText

exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
<body>
 ...
</body>

exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText

exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
<body>
 ...
</body>

exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText

exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText

我尝试使用XDocument doc = XDocument.Parse(str);,但出现异常:

根级别的数据无效。第 1 行,位置 1。

【问题讨论】:

  • 由于整个文件不是 XML,因此您无法将其解析为 XML。您需要手动解析正文标签。
  • @AlG 通过正则表达式获得更好的性能?
  • 小建议,阅读每一行,当你点击时你是inTag,而inTag提取xml,当你点击标签时改变inTag = false。
  • 您确定&lt;body&gt;&lt;/body&gt;之间的内容是格式正确、有效的xml吗?
  • &lt;body&gt; 标签之外的其余文本中是否有任何 XML 特定字符(如 &lt;&gt; 等)?

标签: c# xml


【解决方案1】:

试试下面的代码。如果所有行都以“

            StreamReader reader = new StreamReader(FILENAME, Encoding.UTF8);
            string inputLine = "";
            string str = "";
            while ((inputLine = reader.ReadLine()) != null)
            {
                if (inputLine.Trim().StartsWith("<"))
                {
                    str += inputLine + "\n";
                }
            }

【讨论】:

  • 毫无疑问是 ReadLine()。正则表达式使用大量内存。解析 Regex 时会创建子字符串的层次结构。
【解决方案2】:

虽然这不一定是一个好主意,但您实际上可以通过将其包装在一对标签中来将其解析为 XML,只要您确定它是正确分隔的(即在非 XML 内容中的

例如以下是有效的 XML:

<FileContent>
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
 <body>
 ...
 </body>

exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText

exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText

exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
<body>
 ...
</body>

exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText

exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
<body>
 ...
</body>

exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText

exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
exampleTextexampleTextexampleTextexampleTextexampleTextexampleText
</FileContent>

因此,如果您只是将其包装在一对标签中,您就可以加载它。然后,您可以使用 XPath 访问正文元素。

例如类似(未经测试)

public string GetBodyTagContent (string fileContent)
{
    var xmlDoc = new System.Xml.XmlDocument();
    xmlDoc.LoadXml("<FileContent>" + fileContent + "</FileContent>");
    return string.Join(",", (from n in xmlDoc.SelectNodes("//body") select n.InnerText));
}

【讨论】:

  • 谢谢,但我不能用一对标签包装
【解决方案3】:

html 包含文件内容。
resultList 将给出正文内容列表

简短说明 - 它匹配两个正文标签之间的所有文本。末尾的*? 是非贪婪或惰性量词,允许匹配多个正文标签而不是第一个&lt;body&gt; 和最后一个&lt;/body&gt; 标签中的文本。

RegexOptions options = RegexOptions.IgnoreCase | RegexOptions.Singleline;
Regex regx = new Regex("<body>(?<bodyContents>.*?)</body>", options);
Match matchResult = regx.Match(html);
List<string> resultList = new List<string>();
while (matchResult.Success)
{
       var d = matchResult.Groups["bodyContents"].Value;
       resultList.Add(d.Trim());          
       matchResult = matchResult.NextMatch();
}

正则表达式适用于特定模式(正文标记之间的文本),但是如果正文具有属性或 html 格式不正确,它将失败。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-10
    • 2014-08-10
    • 1970-01-01
    • 1970-01-01
    • 2011-10-30
    • 2015-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多