无法阅读 XML 的第 3 级
Can't Read 3rd level of XML
我不是 XML 专家并且已经好几年没有用它编写代码了。我的任务是将以下 XML 文件读取到 C# 程序中进行处理。我能够阅读大约 2 个级别 - 直到 data index="1" counter="0" 行。但是我无法阅读 bit index="1" value="false" 行。我的 classes 有问题吗?
此外,如何更改 class 以添加索引行的名称属性?
我尝试了将源代码 XML 复制到空 C# class 和 运行 它以及它创建的 class 的技巧。然而还是不行。
这是我要阅读的内容:
<?xml version="1.0"?>
-<mibscalar link="http://1.1.1.1/v1/mib/objs/inputPointGroupStatus?type=xml" type="readonly" name="inputPointGroupStatus">
-<index name="index1">
-<data index="1">
-<index name="index2">
-<data index="1" counter="0">
<bit index="1" value="false"/>
<bit index="2" value="false"/>
<bit index="3" value="false"/>
<bit index="4" value="false"/>
<bit index="5" value="false"/>
<bit index="6" value="false"/>
<bit index="7" value="false"/>
<bit index="8" value="false"/>
</data>
+<data index="2" counter="0">
+<data index="3" counter="0">
+<data index="4" counter="0">
+<data index="5" counter="0">
+<data index="6" counter="0">
+<data index="7" counter="0">
+<data index="8" counter="0">
+<data index="9" counter="0">
+<data index="10" counter="0">
+<data index="11" counter="0">
+<data index="12" counter="0">
+<data index="13" counter="0">
+<data index="14" counter="0">
+<data index="15" counter="0">
+<data index="16" counter="0">
</index>
</data>
+<data index="2">
+<data index="3">
+<data index="4">
+<data index="5">
+<data index="6">
+<data index="7">
+<data index="8">
+<data index="9">
+<data index="10">
</index>
</mibscalar>
代码如下:
public static AtcLoopsStatusMibData ExecuteGetLoopsStatus(string ip, string command)
{
AtcLoopsStatusMibData mib;
string uri = string.Format(API_FORMAT_STR, ip, command);
string msg = $"Calling {uri}";
Xlog.LogVerbose(msg);
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "GET";
request.Timeout = 15 * 1000;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
XmlSerializer serializer = new XmlSerializer(typeof(AtcLoopsStatusMibData));
mib = (AtcLoopsStatusMibData)serializer.Deserialize(reader);
}
catch (Exception ex)
{
msg = $"Call to {uri} failed: {ex.Message}";
Xlog.LogError(msg);
throw;
}
return mib;
}
这是 classes:
[XmlRootAttribute("mibscalar")]
public class AtcLoopsStatusMibData
{
[XmlAttribute("name")]
public string Name { get; set; }
[XmlAttribute("link")]
public string Link { get; set; }
[XmlArray("index")]
[XmlArrayItem("data", typeof(Data1MibElement))]
public List<Data1MibElement> Data1List { get; set; }
[XmlElement("data")]
public Data1MibElement Data { get; set; }
/// <summary>
/// Default Constructor
/// </summary>
public AtcLoopsStatusMibData()
{
Data1List = new List<Data1MibElement>();
}
/// <summary>
/// Sets the "Link" property that is required when sending Mib object
/// to ATC.
/// </summary>
/// <param name="ip">IP Address of the ATC</param>
/// <param name="commandName">Name of the API command call</param>
public void SetLinkAndName(string ip, string commandName)
{
Link = string.Format(HttpHelper.API_FORMAT_STR, ip, commandName);
Name = commandName;
}
}
/// <summary>
/// Secondary object inside the MIB returned by the ATC
/// for detector loop status.
/// This object primary
/// holds the values of the request or command.
/// </summary>
[Serializable]
public class Data1MibElement
{
[XmlAttribute("index")]
public int Index { get; set; }
[XmlArray("index")]
[XmlArrayItem("data", typeof(Data2MibElement))]
public List<Data2MibElement> Data2List { get; set; }
[XmlElement("data")]
public Data2MibElement Data { get; set; }
/// <summary>
/// Default Constructor
/// </summary>
public Data1MibElement()
{
Data2List = new List<Data2MibElement>();
}
/// <summary>
/// Constructor used when building the LoopsStatus MIB object
/// </summary>
/// <param name="index">Loop # (1-6) </param>
/// <param name="counter">Detector loop status value </param>
public Data1MibElement(int index)
{
Index = index;
}
}
/// <summary>
/// Secondary object inside the MIB returned by the ATC
/// for detector loop status.
/// This object primary
/// holds the values of the request or command.
/// </summary>
[Serializable]
public class Data2MibElement
{
[XmlAttribute("index")]
public int Index { get; set; }
[XmlAttribute("counter")]
public int Counter { get; set; }
[XmlArray("bit")]
public List<BitMibElement> BitList { get; set; }
/// <summary>
/// Default Constructor
/// </summary>
public Data2MibElement()
{
BitList = new List<BitMibElement>();
}
/// <summary>
/// Constructor used when building the LoopsStatus MIB object
/// </summary>
/// <param name="index">Loop # (1-6) </param>
/// <param name="counter">Detector loop status value </param>
public Data2MibElement(int index, int counter)
{
Index = index;
Counter = counter;
}
}
/// <summary>
/// Secondary object inside the MIB returned by the ATC
/// for detector loop status.
/// This object primary
/// holds the values of the request or command.
/// </summary>
[Serializable]
public class BitMibElement
{
[XmlAttribute("index")]
public int Index { get; set; }
[XmlAttribute("value")]
public string Value { get; set; }
/// <summary>
/// Default Constructor
/// </summary>
public BitMibElement()
{
}
/// <summary>
/// Constructor used when building the BitMibElement MIB object
/// </summary>
/// <param name="index">Loop # (1-6) </param>
/// <param name="value">Detector loop status value </param>
public BitMibElement(int index, string value)
{
Index = index;
Value = value;
}
}
这是我在调试器中看到的并创建为输出 XML 文件:
<?xml version="1.0" encoding="UTF-8"?>
-<mibscalar link="http://1.1.1.1/v1/mib/objs/inputPointGroupStatus?type=xml" name="inputPointGroupStatus" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-<index>
-<data index="1">
-<index>
-<data index="1" counter="0">
<bit/>
</data>
-<data index="2" counter="0">
<bit/>
</data>
-<data index="3" counter="0">
<bit/>
</data>
-<data index="4" counter="0">
<bit/>
</data>
-<data index="5" counter="0">
<bit/>
</data>
-<data index="6" counter="0">
<bit/>
</data>
-<data index="7" counter="0">
<bit/>
</data>
-<data index="8" counter="0">
<bit/>
</data>
-<data index="9" counter="0">
<bit/>
</data>
-<data index="10" counter="0">
<bit/>
</data>
-<data index="11" counter="0">
<bit/>
</data>
-<data index="12" counter="0">
<bit/>
</data>
-<data index="13" counter="0">
<bit/>
</data>
-<data index="14" counter="0">
<bit/>
</data>
-<data index="15" counter="0">
<bit/>
</data>
-<data index="16" counter="0">
<bit/>
</data>
</index>
</data>
+<data index="2">
+<data index="3">
+<data index="4">
+<data index="5">
+<data index="6">
+<data index="7">
+<data index="8">
+<data index="9">
+<data index="10">
</index>
</mibscalar>
没有 + 和 - 字符 - 复制每个数据部分下的位部分以完整查看完整文件。如果这个网页允许我插入那么长的内容,我可以为您做。
<?xml version="1.0"?>
<mibscalar link="http://1.1.1.1/v1/mib/objs/inputPointGroupStatus?type=xml" type="readonly" name="inputPointGroupStatus">
<index name="index1">
<data index="1">
<index name="index2">
<data index="1" counter="0">
<bit index="1" value="false"/>
<bit index="2" value="false"/>
<bit index="3" value="false"/>
<bit index="4" value="false"/>
<bit index="5" value="false"/>
<bit index="6" value="false"/>
<bit index="7" value="false"/>
<bit index="8" value="false"/>
</data>
<data index="2" counter="0" />
<data index="3" counter="0" />
<data index="4" counter="0" />
<data index="5" counter="0" />
<data index="6" counter="0" />
<data index="7" counter="0" />
<data index="8" counter="0" />
<data index="9" counter="0" />
<data index="10" counter="0" />
<data index="11" counter="0" />
<data index="12" counter="0" />
<data index="13" counter="0" />
<data index="14" counter="0" />
<data index="15" counter="0" />
<data index="16" counter="0" />
</index>
</data>
<data index="2" />
<data index="3" />
<data index="4" />
<data index="5" />
<data index="6" />
<data index="7" />
<data index="8" />
<data index="9" />
<data index="10" />
</index>
</mibscalar>
从 XML 生成 c# 类 的工具,例如 xsd.exe
and https://xmltocsharp.azurewebsites.net/ 在创建类型以使用给定的 XML 时非常有用,但它们有局限性。可能遇到的一个限制是它们无法正确检测 递归数据结构 ,即直接或间接包含自身其他实例的类型。这就是您所拥有的。
您的 XML 元素表现出的嵌套关系如下:
- 根元素
<mibscalar>
有(多个?)<index>
(或 <bit>
?)。
<index>
有多个 <data>
.
<data>
有多个 <index>
或 <bit>
(或两者都有?)。
这个结构可以建模如下:
[XmlRoot(ElementName = "mibscalar")]
public class Mibscalar
{
[XmlAttribute(AttributeName = "link")]
public string Link { get; set; }
[XmlAttribute(AttributeName = "type")]
public string Type { get; set; }
[XmlAttribute(AttributeName = "name")]
public string Name { get; set; }
[XmlElement("bit", typeof(Bit))]
[XmlElement("index", typeof(Index))]
public List<DataItemBase> Items { get; set; }
}
public class Data
{
[XmlAttribute(AttributeName = "index")]
public string Index { get; set; }
[XmlAttribute(AttributeName = "counter")]
public string Counter { get; set; }
[XmlElement("bit", typeof(Bit))]
[XmlElement("index", typeof(Index))]
public List<DataItemBase> Items { get; set; }
}
public abstract class DataItemBase
{
}
public class Index : DataItemBase
{
[XmlAttribute(AttributeName = "name")]
public string Name { get; set; }
[XmlElement(ElementName = "data")]
public List<Data> Data { get; set; }
}
public class Bit : DataItemBase
{
[XmlAttribute(AttributeName = "index")]
public string Index { get; set; }
[XmlAttribute(AttributeName = "value")]
public string Value { get; set; }
}
我使用 https://xmltocsharp.azurewebsites.net/ 生成初始 类,然后修改它们以更正 parent/child 层次结构。
工作示例 .Net fiddle 此处:https://dotnetfiddle.net/9yQ7oN。
我不是 XML 专家并且已经好几年没有用它编写代码了。我的任务是将以下 XML 文件读取到 C# 程序中进行处理。我能够阅读大约 2 个级别 - 直到 data index="1" counter="0" 行。但是我无法阅读 bit index="1" value="false" 行。我的 classes 有问题吗?
此外,如何更改 class 以添加索引行的名称属性?
我尝试了将源代码 XML 复制到空 C# class 和 运行 它以及它创建的 class 的技巧。然而还是不行。
这是我要阅读的内容:
<?xml version="1.0"?>
-<mibscalar link="http://1.1.1.1/v1/mib/objs/inputPointGroupStatus?type=xml" type="readonly" name="inputPointGroupStatus">
-<index name="index1">
-<data index="1">
-<index name="index2">
-<data index="1" counter="0">
<bit index="1" value="false"/>
<bit index="2" value="false"/>
<bit index="3" value="false"/>
<bit index="4" value="false"/>
<bit index="5" value="false"/>
<bit index="6" value="false"/>
<bit index="7" value="false"/>
<bit index="8" value="false"/>
</data>
+<data index="2" counter="0">
+<data index="3" counter="0">
+<data index="4" counter="0">
+<data index="5" counter="0">
+<data index="6" counter="0">
+<data index="7" counter="0">
+<data index="8" counter="0">
+<data index="9" counter="0">
+<data index="10" counter="0">
+<data index="11" counter="0">
+<data index="12" counter="0">
+<data index="13" counter="0">
+<data index="14" counter="0">
+<data index="15" counter="0">
+<data index="16" counter="0">
</index>
</data>
+<data index="2">
+<data index="3">
+<data index="4">
+<data index="5">
+<data index="6">
+<data index="7">
+<data index="8">
+<data index="9">
+<data index="10">
</index>
</mibscalar>
代码如下:
public static AtcLoopsStatusMibData ExecuteGetLoopsStatus(string ip, string command)
{
AtcLoopsStatusMibData mib;
string uri = string.Format(API_FORMAT_STR, ip, command);
string msg = $"Calling {uri}";
Xlog.LogVerbose(msg);
try
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);
request.Method = "GET";
request.Timeout = 15 * 1000;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
XmlSerializer serializer = new XmlSerializer(typeof(AtcLoopsStatusMibData));
mib = (AtcLoopsStatusMibData)serializer.Deserialize(reader);
}
catch (Exception ex)
{
msg = $"Call to {uri} failed: {ex.Message}";
Xlog.LogError(msg);
throw;
}
return mib;
}
这是 classes:
[XmlRootAttribute("mibscalar")]
public class AtcLoopsStatusMibData
{
[XmlAttribute("name")]
public string Name { get; set; }
[XmlAttribute("link")]
public string Link { get; set; }
[XmlArray("index")]
[XmlArrayItem("data", typeof(Data1MibElement))]
public List<Data1MibElement> Data1List { get; set; }
[XmlElement("data")]
public Data1MibElement Data { get; set; }
/// <summary>
/// Default Constructor
/// </summary>
public AtcLoopsStatusMibData()
{
Data1List = new List<Data1MibElement>();
}
/// <summary>
/// Sets the "Link" property that is required when sending Mib object
/// to ATC.
/// </summary>
/// <param name="ip">IP Address of the ATC</param>
/// <param name="commandName">Name of the API command call</param>
public void SetLinkAndName(string ip, string commandName)
{
Link = string.Format(HttpHelper.API_FORMAT_STR, ip, commandName);
Name = commandName;
}
}
/// <summary>
/// Secondary object inside the MIB returned by the ATC
/// for detector loop status.
/// This object primary
/// holds the values of the request or command.
/// </summary>
[Serializable]
public class Data1MibElement
{
[XmlAttribute("index")]
public int Index { get; set; }
[XmlArray("index")]
[XmlArrayItem("data", typeof(Data2MibElement))]
public List<Data2MibElement> Data2List { get; set; }
[XmlElement("data")]
public Data2MibElement Data { get; set; }
/// <summary>
/// Default Constructor
/// </summary>
public Data1MibElement()
{
Data2List = new List<Data2MibElement>();
}
/// <summary>
/// Constructor used when building the LoopsStatus MIB object
/// </summary>
/// <param name="index">Loop # (1-6) </param>
/// <param name="counter">Detector loop status value </param>
public Data1MibElement(int index)
{
Index = index;
}
}
/// <summary>
/// Secondary object inside the MIB returned by the ATC
/// for detector loop status.
/// This object primary
/// holds the values of the request or command.
/// </summary>
[Serializable]
public class Data2MibElement
{
[XmlAttribute("index")]
public int Index { get; set; }
[XmlAttribute("counter")]
public int Counter { get; set; }
[XmlArray("bit")]
public List<BitMibElement> BitList { get; set; }
/// <summary>
/// Default Constructor
/// </summary>
public Data2MibElement()
{
BitList = new List<BitMibElement>();
}
/// <summary>
/// Constructor used when building the LoopsStatus MIB object
/// </summary>
/// <param name="index">Loop # (1-6) </param>
/// <param name="counter">Detector loop status value </param>
public Data2MibElement(int index, int counter)
{
Index = index;
Counter = counter;
}
}
/// <summary>
/// Secondary object inside the MIB returned by the ATC
/// for detector loop status.
/// This object primary
/// holds the values of the request or command.
/// </summary>
[Serializable]
public class BitMibElement
{
[XmlAttribute("index")]
public int Index { get; set; }
[XmlAttribute("value")]
public string Value { get; set; }
/// <summary>
/// Default Constructor
/// </summary>
public BitMibElement()
{
}
/// <summary>
/// Constructor used when building the BitMibElement MIB object
/// </summary>
/// <param name="index">Loop # (1-6) </param>
/// <param name="value">Detector loop status value </param>
public BitMibElement(int index, string value)
{
Index = index;
Value = value;
}
}
这是我在调试器中看到的并创建为输出 XML 文件:
<?xml version="1.0" encoding="UTF-8"?>
-<mibscalar link="http://1.1.1.1/v1/mib/objs/inputPointGroupStatus?type=xml" name="inputPointGroupStatus" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-<index>
-<data index="1">
-<index>
-<data index="1" counter="0">
<bit/>
</data>
-<data index="2" counter="0">
<bit/>
</data>
-<data index="3" counter="0">
<bit/>
</data>
-<data index="4" counter="0">
<bit/>
</data>
-<data index="5" counter="0">
<bit/>
</data>
-<data index="6" counter="0">
<bit/>
</data>
-<data index="7" counter="0">
<bit/>
</data>
-<data index="8" counter="0">
<bit/>
</data>
-<data index="9" counter="0">
<bit/>
</data>
-<data index="10" counter="0">
<bit/>
</data>
-<data index="11" counter="0">
<bit/>
</data>
-<data index="12" counter="0">
<bit/>
</data>
-<data index="13" counter="0">
<bit/>
</data>
-<data index="14" counter="0">
<bit/>
</data>
-<data index="15" counter="0">
<bit/>
</data>
-<data index="16" counter="0">
<bit/>
</data>
</index>
</data>
+<data index="2">
+<data index="3">
+<data index="4">
+<data index="5">
+<data index="6">
+<data index="7">
+<data index="8">
+<data index="9">
+<data index="10">
</index>
</mibscalar>
没有 + 和 - 字符 - 复制每个数据部分下的位部分以完整查看完整文件。如果这个网页允许我插入那么长的内容,我可以为您做。
<?xml version="1.0"?>
<mibscalar link="http://1.1.1.1/v1/mib/objs/inputPointGroupStatus?type=xml" type="readonly" name="inputPointGroupStatus">
<index name="index1">
<data index="1">
<index name="index2">
<data index="1" counter="0">
<bit index="1" value="false"/>
<bit index="2" value="false"/>
<bit index="3" value="false"/>
<bit index="4" value="false"/>
<bit index="5" value="false"/>
<bit index="6" value="false"/>
<bit index="7" value="false"/>
<bit index="8" value="false"/>
</data>
<data index="2" counter="0" />
<data index="3" counter="0" />
<data index="4" counter="0" />
<data index="5" counter="0" />
<data index="6" counter="0" />
<data index="7" counter="0" />
<data index="8" counter="0" />
<data index="9" counter="0" />
<data index="10" counter="0" />
<data index="11" counter="0" />
<data index="12" counter="0" />
<data index="13" counter="0" />
<data index="14" counter="0" />
<data index="15" counter="0" />
<data index="16" counter="0" />
</index>
</data>
<data index="2" />
<data index="3" />
<data index="4" />
<data index="5" />
<data index="6" />
<data index="7" />
<data index="8" />
<data index="9" />
<data index="10" />
</index>
</mibscalar>
从 XML 生成 c# 类 的工具,例如 xsd.exe
and https://xmltocsharp.azurewebsites.net/ 在创建类型以使用给定的 XML 时非常有用,但它们有局限性。可能遇到的一个限制是它们无法正确检测 递归数据结构 ,即直接或间接包含自身其他实例的类型。这就是您所拥有的。
您的 XML 元素表现出的嵌套关系如下:
- 根元素
<mibscalar>
有(多个?)<index>
(或<bit>
?)。 <index>
有多个<data>
.<data>
有多个<index>
或<bit>
(或两者都有?)。
这个结构可以建模如下:
[XmlRoot(ElementName = "mibscalar")]
public class Mibscalar
{
[XmlAttribute(AttributeName = "link")]
public string Link { get; set; }
[XmlAttribute(AttributeName = "type")]
public string Type { get; set; }
[XmlAttribute(AttributeName = "name")]
public string Name { get; set; }
[XmlElement("bit", typeof(Bit))]
[XmlElement("index", typeof(Index))]
public List<DataItemBase> Items { get; set; }
}
public class Data
{
[XmlAttribute(AttributeName = "index")]
public string Index { get; set; }
[XmlAttribute(AttributeName = "counter")]
public string Counter { get; set; }
[XmlElement("bit", typeof(Bit))]
[XmlElement("index", typeof(Index))]
public List<DataItemBase> Items { get; set; }
}
public abstract class DataItemBase
{
}
public class Index : DataItemBase
{
[XmlAttribute(AttributeName = "name")]
public string Name { get; set; }
[XmlElement(ElementName = "data")]
public List<Data> Data { get; set; }
}
public class Bit : DataItemBase
{
[XmlAttribute(AttributeName = "index")]
public string Index { get; set; }
[XmlAttribute(AttributeName = "value")]
public string Value { get; set; }
}
我使用 https://xmltocsharp.azurewebsites.net/ 生成初始 类,然后修改它们以更正 parent/child 层次结构。
工作示例 .Net fiddle 此处:https://dotnetfiddle.net/9yQ7oN。