使用C#分析XML文件extrate中的Null值时出错



我需要一些XML文件解析方面的帮助。当为每个循环迭代时,我在XML文件中得到错误while 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如下:

"<SensorBlob版本xsi:nil=";真";xmlns:xsi=";http://www.w3.org/2001/XMLSchema-instance">quot

示例源代码:

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的XmlSerializer有时会使用文档中指定的xsi:nil="true"null值序列化为空XML元素:

将对象序列化到XML文档中时:如果XmlSerializer类遇到与XML元素对应的对象的空引用,则它会生成一个指定xsi:nil="true"的元素,或者完全忽略该元素,具体取决于是否应用nillable="true"设置。

如果您的XML是用具有空值的xsi:nil="true"属性的元素生成的,并且您正在使用LINQ to XML手动进行分析,则需要手动检查它们。

首先,介绍以下扩展方法:

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);

在这里,我假设您需要区分丢失<SensorBlobVersion>元素和空<SensorBlobVersion xsi:nil="true" />元素的情况。如果你不需要区分,你可以将两种情况分配给相同的值,例如:

if (sensorBlobVersionElement.IsNull()) 
mes.SensorBlobVersion = null; // Element was missing or null
else
mes.SensorBlobVersion = (int?)(sensorBlobVersionElement);

在这里演示小提琴。

相关内容

最新更新