提问人:skt 提问时间:8/19/2022 最后编辑:Olivier Jacot-Descombesskt 更新时间:8/19/2022 访问量:706
使用 C 解析 XML 文件 extrate 中的 Null 值时出错#
Getting Error while Parsing the Null value in XML file extrate using C#
问:
我需要有关XML文件解析的小帮助。我在每个循环迭代时收到错误,而 XML 文件中的 Null 值。 如何使用具有 Null 值的不同数据类型进行解析。
源 XML 文件:
<XMLList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<measList>
<Measurement>
<MeasurementGuid>87ae41e0-e9ec-4570-83c1-75fbfc96db17</MeasurementGuid>
<SequenceNumber>953</SequenceNumber>
<Time>2020-10-07T15:39:06</Time>
<SensorBlobVersion xsi:nil="true" />
</Measurement>
<Measurement>
<MeasurementGuid>1243234-e9ec-2324-83c1-43fbfc96db17</MeasurementGuid>
<SequenceNumber>111</SequenceNumber>
<Time>2022-11-07T15:39:06</Time>
<SensorBlobVersion xsi:nil="true" />
</Measurement>
</measList>
</XMLList>
我收到 SensorBlobVersion 的错误。它是空的。错误:“输入字符串的格式不正确。
当我将调试点放在 SensorBlobVersion 时,我可以看到 Null,如下所示:
“<SensorBlobVersion xsi:nil=”true“ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance“ />”
示例源代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace XMLFileUploader
{
using System.Linq;
using System.Xml;
using System.Xml.Linq;
namespace XMLFileUploader
{
public static class ExtractLogFile
{
public static void ExtractData(string filePath)
{
XElement root = XElement.Load(filePath);
IEnumerable<XElement> tests =
from el in root.Elements("measList")
select el;
IEnumerable<XElement> measList =
from el2 in tests.Elements("Measurement")
select el2;
foreach (XElement el2 in measList)
{
Measurement mes = new Measurement();
if (el2.NodeType == XmlNodeType.Element && el2.Name == "Measurement")
{
mes.MeasurementInfoGuid = (String)el2.Element("MeasurementGuid");
mes.SequenceNumber = (int)el2.Element("SequenceNumber");
mes.Time = (DateTime)el2.Element("Time");
if (el2.Element("SensorBlobVersion") == null)
{
mes.SensorBlobVersion = 0;
}
else
{
mes.SensorBlobVersion = (int?)(el2.Element("SensorBlobVersion")); // **ERROR AT THIS LINE**
}
}
}
}
public class Measurement
{
public String MeasurementInfoGuid { get; set; }
public int SequenceNumber { get; set; }
public DateTime Time { get; set; }
public int? SensorBlobVersion { get; set; }
}
}
}
}
答:
我让代码简单了一点:
public static class ExtractLogFile
{
public static void ExtractData(string filePath)
{
XDocument doc = XDocument.Load(filePath);
IEnumerable<XElement> measList = doc.Descendants("Measurement");
foreach (XElement el2 in measList)
{
Measurement mes = new Measurement();
mes.MeasurementInfoGuid = (String)el2.Element("MeasurementGuid");
mes.SequenceNumber = (int)el2.Element("SequenceNumber");
mes.Time = (DateTime)el2.Element("Time");
if (el2.Element("SensorBlobVersion") == null)
{
mes.SensorBlobVersion = 0;
}
else
{
int version = 0;
Boolean isInt = int.TryParse((string)el2.Element("SensorBlobVersion"),out version );
mes.SensorBlobVersion = isInt ? version : null;
}
}
}
public class Measurement
{
public String MeasurementInfoGuid { get; set; }
public int SequenceNumber { get; set; }
public DateTime Time { get; set; }
public int? SensorBlobVersion { get; set; }
}
}
属性 xsi:nil
是一个 w3c 标准属性,指示元素没有内容。Microsoft 有时会将值序列化为空 XML 元素,如文档中指定的那样:XmlSerializer
null
xsi:nil="true"
将对象序列化为 XML 文档时:如果类遇到对应于 XML 元素的对象的空引用,则它会生成一个指定或完全忽略该元素的元素,具体取决于是否应用设置。
XmlSerializer
xsi:nil="true"
nillable="true"
如果 XML 是使用具有 null 值属性的元素生成的,并且您使用 LINQ to XML 手动分析,则需要手动检查它们。xsi:nil="true"
首先,介绍以下扩展方法:
public static class XNodeExtensions
{
static readonly XNamespace xsi = @"http://www.w3.org/2001/XMLSchema-instance";
static readonly XName xsiNil = xsi + "nil";
public static bool IsNull(this XElement? element) => element == null || element.Attribute(xsiNil)?.Value == "true";
}
现在修改代码,如下所示:
var sensorBlobVersionElement = el2.Element("SensorBlobVersion");
if (sensorBlobVersionElement == null)
mes.SensorBlobVersion = 0; // Element was missing, assign to 0
else if (sensorBlobVersionElement.IsNull())
mes.SensorBlobVersion = null; // Element was present but explicitly null
else
mes.SensorBlobVersion = (int?)(sensorBlobVersionElement);
在这里,我假设您需要区分缺少元素和 null 元素的情况。如果不需要区分,可以将两种情况分配给相同的值,例如:<SensorBlobVersion>
<SensorBlobVersion xsi:nil="true" />
if (sensorBlobVersionElement.IsNull())
mes.SensorBlobVersion = null; // Element was missing or null
else
mes.SensorBlobVersion = (int?)(sensorBlobVersionElement);
评论