如何在XML中的特定元素中反序列化属性的特定值?

时间:2012-11-20 14:21:12

标签: c# xml xml-parsing deserialization xml-deserialization

我只需要使用System.XML读取Packet Name =“PacketOut”中声明的UnityObject值。 任何帮助将不胜感激,提前感谢。 这是XML剪辑:

 <IOConfig>

    <Packet Name="PacketOut" RemoteAddress="10.0.2.250" RemotePort="2020" NetworkInterface="ETH0" >
      <Signal Type="float" Name="x_out"        Unit="m/s"      Routing=""        UnityObject="CraneBoom"    ></Signal>
      <Signal Type="float" Name="y_out"        Unit="m/s"      Routing=""        UnityObject="CraneBoom"    ></Signal>
      <Signal Type="float" Name="z_out"        Unit="m/s"      Routing=""        UnityObject="CraneBoom"    ></Signal>
      <Signal Type="float" Name="alpha_out"    Unit="m/s"      Routing=""        UnityObject="CraneBoom"    ></Signal>
      <Signal Type="float" Name="theta_out"    Unit="m/s"      Routing=""        UnityObject="CraneBoom"    ></Signal>
      <Signal Type="float" Name="phi_out"      Unit="m/s"      Routing=""        UnityObject="CraneBoom"    ></Signal>

      <Signal Type="float" Name="x_out1"        Unit="m/s"      Routing=""       UnityObject="CraneSlewing" ></Signal>
      <Signal Type="float" Name="y_out1"        Unit="m/s"      Routing=""       UnityObject="CraneSlewing" ></Signal>
      <Signal Type="float" Name="z_out1"        Unit="m/s"      Routing=""       UnityObject="CraneSlewing" ></Signal>
      <Signal Type="float" Name="alpha_out1"    Unit="m/s"      Routing=""       UnityObject="CraneSlewing" ></Signal>
      <Signal Type="float" Name="theta_out1"    Unit="m/s"      Routing=""       UnityObject="CraneSlewing" ></Signal>
      <Signal Type="float" Name="phi_out1"      Unit="m/s"      Routing=""       UnityObject="CraneSlewing" ></Signal>

      <Signal Type="float" Name="x_out2"        Unit="m/s"      Routing=""        UnityObject="CraneBoom"    ></Signal>
      <Signal Type="float" Name="y_out2"        Unit="m/s"      Routing=""        UnityObject="CraneBoom"    ></Signal>
      <Signal Type="float" Name="z_out2"        Unit="m/s"      Routing=""        UnityObject="CraneBoom"    ></Signal>
      <Signal Type="float" Name="alpha_out2"    Unit="m/s"      Routing=""        UnityObject="CraneBoom"    ></Signal>
      <Signal Type="float" Name="theta_out2"    Unit="m/s"      Routing=""        UnityObject="CraneBoom"    ></Signal>
      <Signal Type="float" Name="phi_out2"      Unit="m/s"      Routing=""        UnityObject="CraneBoom"    ></Signal>
      </Packet>


    <Packet Name="PacketIn" LocalPort="2021" NetworkInterface="ETH0">
      <Signal Type="float" Name="x_in"        Unit="m/s"      Routing=""          UnityObject="CraneBoomCrash"></Signal>
      <Signal Type="float" Name="y_in"        Unit="m/s"      Routing=""          UnityObject="CraneBoomCrash"></Signal>
      <Signal Type="float" Name="z_in"        Unit="m/s"      Routing=""          UnityObject="CraneBoomCrash"></Signal>
      <Signal Type="float" Name="alpha_in"    Unit="m/s"      Routing=""          UnityObject="CraneBoomCrash"></Signal>
      <Signal Type="float" Name="theta_in"    Unit="m/s"      Routing=""          UnityObject="CraneBoomCrash"></Signal>
      <Signal Type="float" Name="phi_in"      Unit="m/s"      Routing=""          UnityObject="CraneBoomCrash"></Signal>

    <Signal Type="float" Name="x_in1"      Unit="m/s"      Routing=""          UnityObject="CraneBoomCrash"></Signal>
      <Signal Type="float" Name="y_in1"    Unit="m/s"      Routing=""          UnityObject="CraneBoomCrash"></Signal>
      <Signal Type="float" Name="z_in1"    Unit="m/s"      Routing=""          UnityObject="CraneBoomCrash"></Signal>
      <Signal Type="float" Name="alpha_in1"  Unit="m/s"      Routing=""          UnityObject="CraneBoomCrash"></Signal>
      <Signal Type="float" Name="theta_in1"  Unit="m/s"      Routing=""          UnityObject="CraneBoomCrash"></Signal>
      <Signal Type="float" Name="phi_in1"    Unit="m/s"      Routing=""          UnityObject="CraneBoomCrash"></Signal>
  </Packet>

  </IOConfig>

我尝试在下面剪切代码,它在XML的其余部分获取UnityObject的所有值。

using UnityEngine;
using System.IO;
using System.Xml;
using System.Text; 
using System.Collections.Generic;
using System.Collections;

public class xmlreader : MonoBehaviour
{
    public static List<string> values; 
    public string gameObjects;

    public XmlReaderSettings settings;


    void Start ()
    {
            XmlReaderSettings settings = new XmlReaderSettings();
            settings.IgnoreWhitespace = true;
            settings.IgnoreComments = true;
            values = new List<string>();
        using ( XmlReader reader = XmlReader.Create("D://Docs/Unity3D/cdp/UDPApplication/Components/UDPIOServer.xml", settings) ) {

        while ( reader.Read() ) {
                    if ( reader.NodeType == XmlNodeType.Element) {

                        if ( reader.HasAttributes ) {

                        if ( reader.GetAttribute("UnityObject") != null ) {
                            gameObjects = reader.GetAttribute("UnityObject");
                            values.Add(gameObjects);



                }
                                }
                            }


                            }
                        }



    }
                }

2 个答案:

答案 0 :(得分:1)

这可以通过非常简单的XPath表达式完成:

XmlDocument doc = new XmlDocument();
doc.Load("D://Docs/Unity3D/cdp/UDPApplication/Components/UDPIOServer.xml");

XmlNodeList nodes =
    doc.SelectNodes("IOConfig/Packet[@Name='PacketOut']/Signal/@UnityObject");

List<string> result = new List<string>();
foreach (XmlNode node in nodes)
{
    result.Add(node.Value);
}

result现在是List<string>,看起来像{"CraneBoom", "CraneBoom", ...}

此解决方案仅使用System.Collections.GenericSystem.Xml

答案 1 :(得分:0)

您知道xsd.exe,它是Visual Studio附带的工具吗?

请注意,我重命名了您的xml文件IOConfig.xml

尝试以下方法:

从文件中推断xsd架构并生成IOConfig.xsd

xsd.exe IOConfig.xml

生成一个漂亮的IOConfig.cs文件,可以帮助您完成旅程

xsd.exe IOConfig.xsd /classes

现在你只需要反序列化并处理你的对象:

    public void ReadIOConfig()
    {
        string fileName = @"C:\IOConfig.xml";
        XmlSerializer xs = new XmlSerializer(typeof(IOConfig));
        XmlReader reader = XmlReader.Create(fileName);
        IOConfig config = xs.Deserialize(reader) as IOConfig;
        var packetOut = (from configPacket in config.Items
                         where configPacket.Name == "PacketOut"
                         select configPacket).First();

        foreach (var signal in packetOut.Signal)
            Console.WriteLine(signal.UnityObject);

    }

使用生成的文件:

//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.269
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

using System.Xml.Serialization;

// 
// This source code was auto-generated by xsd, Version=4.0.30319.1.
// 


/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class IOConfig
{

    private IOConfigPacket[] itemsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("Packet", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public IOConfigPacket[] Items
    {
        get
        {
            return this.itemsField;
        }
        set
        {
            this.itemsField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class IOConfigPacket
{

    private IOConfigPacketSignal[] signalField;

    private string nameField;

    private string remoteAddressField;

    private string remotePortField;

    private string networkInterfaceField;

    private string localPortField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("Signal", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public IOConfigPacketSignal[] Signal
    {
        get
        {
            return this.signalField;
        }
        set
        {
            this.signalField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Name
    {
        get
        {
            return this.nameField;
        }
        set
        {
            this.nameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string RemoteAddress
    {
        get
        {
            return this.remoteAddressField;
        }
        set
        {
            this.remoteAddressField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string RemotePort
    {
        get
        {
            return this.remotePortField;
        }
        set
        {
            this.remotePortField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string NetworkInterface
    {
        get
        {
            return this.networkInterfaceField;
        }
        set
        {
            this.networkInterfaceField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string LocalPort
    {
        get
        {
            return this.localPortField;
        }
        set
        {
            this.localPortField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class IOConfigPacketSignal
{

    private string typeField;

    private string nameField;

    private string unitField;

    private string routingField;

    private string unityObjectField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Type
    {
        get
        {
            return this.typeField;
        }
        set
        {
            this.typeField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Name
    {
        get
        {
            return this.nameField;
        }
        set
        {
            this.nameField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Unit
    {
        get
        {
            return this.unitField;
        }
        set
        {
            this.unitField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Routing
    {
        get
        {
            return this.routingField;
        }
        set
        {
            this.routingField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string UnityObject
    {
        get
        {
            return this.unityObjectField;
        }
        set
        {
            this.unityObjectField = value;
        }
    }
}