[英]Retrieving text from XML with C#
我有一个包含以下内容的文本文件:
<Person>
<Prenom>Jack</Prenom>
<Nom>Jhon</Nom>
<Adresse>4 rue de la Mélandine</Adresse>
<Tél></Tél>
<Email>email@gmail.com</Email>
<PhotoPath>c:\Program Files\Zonedetec\Gestionnaire de tâche v2\Img\5295f1ea-372a-4f2f-8f32-c52e8a48cc0839105.png</PhotoPath>
<Age>19</Age>
<Id>4640434</Id>
</Person>
<Person>
<Prenom>Jean</Prenom>
<Nom>Delamar</Nom>
<Adresse>13 rue de la Mélandine</Adresse>
<Tél></Tél>
<Email>email@gmail.com</Email>
<PhotoPath>c:\Program Files\Zonedetec\Gestionnaire de tâche v2\Img\5295f1ea-372a-4f2f-8f32-c52e8a48cc0839105.png</PhotoPath>
<Age>19</Age>
<Id>4640434</Id>
</Person>
我想检索标签之间的所有值例如,在列表中,我想检索和
我怎么能这样做?
我试过这个:
internal static void LoadPerson()
{
string data = File.ReadAllText(Main.PersonnePath);
Regex regex = new Regex("<Person>(.*)</Person>");
var v = regex.Match(data);
string s = v.Groups[1].ToString();
MessageBox.Show(s);
}
除了 s 什么都不包含
你能帮助我吗? 谢谢你。
由于您的文件具有 XML 格式,因此您可以使用XmlSerializer
来读取它,这比手动解析要轻松
首先创建一个Person
类(或在 Visual Studio 中使用Edit -> Paste special -> Paste XML as classes 生成)
[Serializable]
public class Person
{
private string _prenomField;
private string _nomField;
private string _adresseField;
private object _télField;
private string _emailField;
private string _photoPathField;
private byte _ageField;
private uint _idField;
public string Prenom
{
get => _prenomField;
set => _prenomField = value;
}
public string Nom
{
get => _nomField;
set => _nomField = value;
}
public string Adresse
{
get => _adresseField;
set => _adresseField = value;
}
public object Tél
{
get => _télField;
set => _télField = value;
}
public string Email
{
get => _emailField;
set => _emailField = value;
}
public string PhotoPath
{
get => _photoPathField;
set => _photoPathField = value;
}
public byte Age
{
get => _ageField;
set => _ageField = value;
}
public uint Id
{
get => _idField;
set => _idField = value;
}
}
比更新一点文件结构(你必须有一个根标签)
<?xml version="1.0" encoding="utf-8" ?>
<people>
<Person>
<Prenom>Jack</Prenom>
<Nom>Jhon</Nom>
<Adresse>4 rue de la Mélandine</Adresse>
<Tél></Tél>
<Email>email@gmail.com</Email>
<PhotoPath>c:\Program Files\Zonedetec\Gestionnaire de tâche v2\Img\5295f1ea-372a-4f2f-8f32-c52e8a48cc0839105.png</PhotoPath>
<Age>19</Age>
<Id>4640434</Id>
</Person>
<Person>
<Prenom>Jean</Prenom>
<Nom>Delamar</Nom>
<Adresse>13 rue de la Mélandine</Adresse>
<Tél></Tél>
<Email>email@gmail.com</Email>
<PhotoPath>c:\Program Files\Zonedetec\Gestionnaire de tâche v2\Img\5295f1ea-372a-4f2f-8f32-c52e8a48cc0839105.png</PhotoPath>
<Age>19</Age>
<Id>4640434</Id>
</Person>
</people>
最后解析它
var mySerializer = new XmlSerializer(typeof(Person[]), new XmlRootAttribute("people"));
Person[] people;
using (var fileStream = new FileStream(Main.PersonnePath, FileMode.Open))
{
people = (Person[])mySerializer.Deserialize(fileStream);
}
不要忘记添加using System.Xml.Serialization;
命名空间。 反序列化后people
数组将包含您需要的所有值,您可以将它们格式化为任何字符串/任何您想要的。 这里最好的选择是覆盖Person
类的ToString()
方法来获取对象所需的字符串表示
如果您只需要这些值作为纯文本。 您可以使用正则表达式或 XMLSerializer 或 (Linq to XML)。
在选择一种方法或另一种方法之前,您需要分析的是:
1)我需要做什么?
1.a) 如果您只需要每个标签内的纯文本。 而且你不会做任何验证/计算/重新解析器。 您可以轻松地使用这两种方法。
1.a.1) 使用正则表达式:
public List<string> GetValueByRegex(string input)
{
string pattern = @"<Person>([\s\S]*?)</Person>";
var matches = Regex.Matches(input, pattern);
if (matches.All(m => !m.Success))
return null;
var result = new List<string>();
foreach (Match match in matches)
{
result.Add(match.Groups[1].Value);
}
return result;
}
1.a.2) 使用 XDocument 解析 Xml 字符串
重要提示:XDocument 要求您的 XML 有一个根标签才能工作。 因为你的 XML 有两个根标签。 我用字符串插值
$"<root>{input}</root>"
强制它
public List<string> GetValueByXmlParse(string input)
{
var result = new List<string>();
var ensureThereAreOnlyOneRootTag = $"<root>{input}</root>";
XDocument xmlDocument = XDocument.Parse(ensureThereAreOnlyOneRootTag);
foreach(var personXml in xmlDocument.Root.Elements("Person"))
{
result.Add(String.Concat(personXml.Nodes()));
}
return result;
}
1.b) 如果您要对从 XML 中提取的数据做任何事情,最好将其解析为对象。
您可以通过复制 XML 值并单击“编辑”>“选择性粘贴”>“将 XML 粘贴为类”来使 Visual Studio 生成一个。
@PavelAnikhouski 已经为此分享了一个很好的例子。
2)我真的需要一个好的表现吗?
为了回答这个问题,我使用 Benchmark nuget 包来比较所有选项。 这是结果:
| Method | Gen 0 | Allocated |
|---------------------- |---------:|----------:|
| GetValueByRegex | 1.2207 | 2688 B |
| GetValueByXmlParse | 115.6006 | 243536 B |
第 0 代:GC 第 0 代每 1000 次操作收集一次
分配:每个操作分配的内存(仅限托管,包括,1KB = 1024B)
所以,答案是:取决于你需要对结果做什么。 我希望我能帮助你做出决定。
此致
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.