Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 安全解析XML_C#_Xml_Xml Documentation - Fatal编程技术网

C# 安全解析XML

C# 安全解析XML,c#,xml,xml-documentation,C#,Xml,Xml Documentation,我被要求编写一个采用以下XML结构的方法,并将其解析为对象列表: <?xml version="1.0" encoding="UTF-8"?> <comments> <comment> <date>11/MAR/2014 10:34am</date> <userid>1</userid> <text>This is a comment. Plea

我被要求编写一个采用以下XML结构的方法,并将其解析为对象列表:

<?xml version="1.0" encoding="UTF-8"?>
<comments>
    <comment>
        <date>11/MAR/2014 10:34am</date>
        <userid>1</userid>
        <text>This is a comment. Please remember to try with some formatting. I'm assuming that some charactors need to be prefixed with a backslash.</text>
    </comment>
    <comment>
        <date>11/MAR/2014 10:37am</date>
        <userid>1</userid>
        <text>This is another comment./r/nIt\'s showing how more than one comment would be stored.\r\n\r\nAlso, this one has some really hardcore escape charactors!</text>
    </comment>
</comments>

2014年3月11日上午10:34
1.
这是一个评论。请记住尝试一些格式设置。我假设某些字符需要加反斜杠作为前缀。
2014年3月11日上午10:37
1.
这是另一条注释。/r/nIt显示了如何存储多条注释。\r\n\r\n此外,这条注释还有一些非常核心的转义字符!
可以有许多“评论”

因此,根据我对XML的基本知识,我尝试了以下方法:

 private List<Comment> XMLToList(string xml)
        {

            var result = new List<Comment>();

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(xml);

            XmlNodeList xnList = xmlDoc.SelectNodes("/comments/comment");

            foreach (XmlNode node in xnList)
            {
                var id = node["userid"].InnerText;
                var date = node["date"].InnerText;
                var text = node["texts"].InnerText;

                result.Add(new Comment
                {
                    Date = DateTime.Parse(date),
                    Text = text,
                    UserID = int.Parse(id)

                });


            }
私有列表XMLToList(字符串xml)
{
var result=新列表();
XmlDocument xmlDoc=新的XmlDocument();
LoadXml(xml);
XmlNodeList xnList=xmlDoc.SelectNodes(“/comments/comment”);
foreach(xnList中的XmlNode节点)
{
var id=node[“userid”]。InnerText;
变量日期=节点[“日期”]。InnerText;
var text=节点[“text”]。InnerText;
结果。添加(新注释
{
Date=DateTime.Parse(日期),
Text=Text,
UserID=int.Parse(id)
});
}
这是可行的,但非常不安全。如果节点丢失了怎么办?错配?等等


有没有办法确保XML文档首先正确格式化? 那么,有没有更安全的方法来获取数据

(我可以修复对日期和int值的解析…这只是一个测试。更多的是我试图解析的节点的访问)


也许可以用Linq完成吗?

您可以用Linq to XML轻松完成:

var comments = XDocument.Parse(xml).Descendants("comment")
            .Select(x => new  Comment
            {
               Date = x.Element("date") != null ? (DateTime)x.Element("date") : default(DateTime),
               Text = (string)x.Element("text"),
               UserID =x.Element("userid") != null ? (int)x.Element("userid") : default(int)
            }).ToList();
关键点是在接收值时使用显式强制转换。我添加了一些null检查以避免
ArgumentNullException
。当您尝试将null强制转换为ValueType时,它会抛出。字符串不是问题,它只是返回为null

如果要确保xml格式有效,可以使用以下方法:

try
{
      // parse the xml file
}
catch (XmlException ex)
{
     // this exception is thrown by Parse method 
     // when the xml file format is invalid
 }

“有没有办法确保XML文档先正确格式化?”您创建了一个模式并根据该模式验证XML。这很有效!现在我只需要找到一种方法来确保此代码的格式正确。下一步我需要的是模式验证。@Craig我理解。最简单的方法是使用try/catch。我将更新我的答案that@Craig你所说的无效模式是什么意思nt以了解文件格式是否无效或是否存在所有必需的元素?因为它们是不同的东西。您可以以不同的方式处理两种情况。如果您希望定义Xml架构并验证Xml,请查看文档:谢谢@Selman22-我们现在讨论的是try/catch想法,而不是n XSD模式检查,这似乎有些过分。我只想确保我的“注释”部分中有“日期”、“用户ID”和“文本”字段,并且这些字段是有效的。Try/Catch可以非常简单地做到这一点。这是一种可接受的模式吗?XML无效的可能性非常小。如果XML没有我上面提到的值,那么t无效。因此,try/catch看起来更简单,也更适合使用。但是,这可以接受吗?@Craig是的。但是您应该删除我的空检查,因为即使某些值为空,它也不会引发异常:)我建议您创建一个方法,例如
ValidateElement
,并在该方法内部检查您的元素,如果我发现s null return false。在尝试选择元素之前,您可以将该方法与
Where
一起使用,并使用
Select
仅获取有效元素。或者,如果您希望确保所有元素都包含必需的元素,则可以轻松删除null检查并使用try-catch。一旦发现null,它将抛出异常。