【问题标题】:Can't Read 3rd level of XML无法读取第三级 XML
【发布时间】:2018-08-06 18:30:45
【问题描述】:

我不是 XML 专家,并且已经好几年没有使用它进行编码了。我的任务是将以下 XML 文件读入 C# 程序进行处理。我能够阅读大约 2 个级别 - 直到 data index="1" counter="0" 行。但是我无法阅读 bit index="1" value="false" 行。我的课有问题吗?

另外,如何更改类以添加索引行的名称属性?

我尝试了将源 XML 复制到一个空的 C# 类并使用它创建的类运行它的技巧。但是还是不行。

这是我要阅读的内容:

<?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;
    }

这里是类:

[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 中,或者它们是某种可视化工具的产物?如果是后者,您认为您可以请edit 您的问题包含实际 XML 的示例,我们可以将其复制并粘贴到控制台应用程序中进行测试?
  • dbc 请查看我添加的内容。只需复制数据索引部分下的位线即可完全复制它。
  • 如果您需要完整版,请告诉我。
  • 更新后的 XML 格式不正确 -- 没有一个 &lt;data index="12" counter="0"&gt; 被正确终止,无论是 &lt;data index="12" counter="0" /&gt; 还是 &lt;/data&gt;
  • dbc,我也注意到了。不幸的是,这是来自硬件设备。不知道是否可以更新固件来纠正这个问题。

标签: c# xml xmlserializer


【解决方案1】:

从 XML 生成 c# 类的工具,例如 xsd.exehttps://xmltocsharp.azurewebsites.net/ 在创建类型以使用某些给定的 XML 时非常有用,但它们有局限性。可能遇到的一个限制是它们无法正确检测递归数据结构,即直接或间接包含自身其他实例的类型。这就是你在这里所拥有的。

您的 XML 元素表现出的嵌套关系如下:

  • 根元素&lt;mibscalar&gt; 有(多个?)&lt;index&gt;(或&lt;bit&gt;?)。
  • &lt;index&gt; 有多个 &lt;data&gt;
  • &lt;data&gt; 有多个 &lt;index&gt;&lt;bit&gt;(或两者都有?)。

这个结构可以建模如下:

[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/ 生成初始类,然后修改它们以更正父/子层次结构。

.Net fiddle 工作示例:https://dotnetfiddle.net/9yQ7oN

【讨论】:

  • 这行得通。我们最终使用了不同的变体。让我们感到困惑的是,当我们可以读取 XML 时,我们会在一些位数组行中看到不同的值。与我们的工程师核实后,他说有问题的阵列正在获得随机值 - 一些关于未在硬件的那部分设置接线的问题。 XML 中较高的位数组是正确的并且工作正常。
猜你喜欢
  • 2012-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-19
  • 1970-01-01
相关资源
最近更新 更多