如何使用具有唯一标识符作为属性的重复标记名称反序列化 XML?
How to deserialize XML with repeating tag name with unique identifier as attribute?
我正在尝试反序列化此 xml,其中所有节点都具有相同的名称,并且具有唯一标识符作为属性。
<configuration>
<setting name="host">
<value>127.0.0.1</value>
</setting>
<setting name="port">
<value>80</value>
</setting>
</configuration>
我想要达到的结果是:
public class Configuration
{
string host { get; set; }
int port { get; set; }
}
我读了上一个问题,但我仍然对它们具有相同的标签名称这一事实感到困惑。
谢谢!
将您的 xml 作为文档加载
XmlDocument doc = new XmlDocument();
doc.LoadXml(your_xml_data);
然后遍历子节点
Configuration configuration = new Configuration();
XmlNode root = doc.FirstChild;
//fill the configuration from the child nodes.
if (root.HasChildNodes)
{
if(root.ChildNodes[0].Name == "host")
{
configuration.host = root.ChildNodes[0].InnerText;
}
if(root.ChildNodes[1].Name == "port")
{
configuration.port = root.ChildNodes[1].InnerText;
}
}
试试这个:
XmlDocument doc = new XmlDocument();
doc.LoadXml("yourxmlhere");
Configuration configuration = new Configuration();
XmlNode root = doc.FirstChild;
if (root.HasChildNodes)
{
foreach (XmlNode item in root.ChildNodes)
{
configuration = SetValueByPropertyName(configuration, item.Attributes["name"].Value, item.FirstChild.InnerText);
}
}
设置值的辅助方法:
public static TInput SetValueByPropertyName<TInput>(TInput obj, string name, string value)
{
PropertyInfo prop = obj.GetType().GetProperty(name);
if (null != prop && prop.CanWrite)
{
if (prop.PropertyType != typeof(String))
{
prop.SetValue(obj, Convert.ChangeType(value, prop.PropertyType), null);
}
else
{
prop.SetValue(obj, value, null);
}
}
return obj;
}
您可以调用它 "old school" 但它有效。
复制 XML(或片段等)并利用 Visual Studio(2015 年(?)和下图是 2017 年)特征 "Paste XML/JSON As Classes"
这对 有效的 XML 有很大帮助 - 特别是对装饰生成的 class 的 "proper" 属性。此外,它只是一个 class,因此您可以根据需要自定义它(同时保留属性)。
对于更复杂的 XML - 例如 namespaces/prefixes,您将非常感激。如果你没有这个工具,你可以使用 XSD.exe
(甚至更老派)——对 XML 文档做同样的事情。
从上面的步骤自动生成 类:
...stumbling with the fact they have the same tag name...
别这样。 XML 元素可以重复 - 经常这样做(例如每个网站的 sitemap.xml
)。生成的 class 将帮助您理解它。这是一个标准 collection/array/list.
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class configuration
{
private configurationSetting[] settingField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("setting")]
public configurationSetting[] setting
{
get
{
return this.settingField;
}
set
{
this.settingField = value;
}
}
}
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class configurationSetting
{
private string valueField;
private string nameField;
/// <remarks/>
public string value
{
get
{
return this.valueField;
}
set
{
this.valueField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string name
{
get
{
return this.nameField;
}
set
{
this.nameField = value;
}
}
}
鉴于以上情况,您可以这样做:
string rawXml = "<configuration><setting name=\"host\"><value>127.0.0.1</value></setting><setting name=\"port\"><value>80</value></setting></configuration>";
var ser = new XmlSerializer(typeof(configuration));
configuration config;
using (TextReader rdr = new StringReader(rawXml))
{
config = (configuration)ser.Deserialize(rdr);
}
foreach (configurationSetting setting in config.setting)
{
Console.WriteLine($"{setting.name} = {setting.value}");
}
输出:
host = 127.0.0.1
port = 80
Hth..
我正在尝试反序列化此 xml,其中所有节点都具有相同的名称,并且具有唯一标识符作为属性。
<configuration>
<setting name="host">
<value>127.0.0.1</value>
</setting>
<setting name="port">
<value>80</value>
</setting>
</configuration>
我想要达到的结果是:
public class Configuration
{
string host { get; set; }
int port { get; set; }
}
我读了上一个问题,但我仍然对它们具有相同的标签名称这一事实感到困惑。
谢谢!
将您的 xml 作为文档加载
XmlDocument doc = new XmlDocument();
doc.LoadXml(your_xml_data);
然后遍历子节点
Configuration configuration = new Configuration();
XmlNode root = doc.FirstChild;
//fill the configuration from the child nodes.
if (root.HasChildNodes)
{
if(root.ChildNodes[0].Name == "host")
{
configuration.host = root.ChildNodes[0].InnerText;
}
if(root.ChildNodes[1].Name == "port")
{
configuration.port = root.ChildNodes[1].InnerText;
}
}
试试这个:
XmlDocument doc = new XmlDocument();
doc.LoadXml("yourxmlhere");
Configuration configuration = new Configuration();
XmlNode root = doc.FirstChild;
if (root.HasChildNodes)
{
foreach (XmlNode item in root.ChildNodes)
{
configuration = SetValueByPropertyName(configuration, item.Attributes["name"].Value, item.FirstChild.InnerText);
}
}
设置值的辅助方法:
public static TInput SetValueByPropertyName<TInput>(TInput obj, string name, string value)
{
PropertyInfo prop = obj.GetType().GetProperty(name);
if (null != prop && prop.CanWrite)
{
if (prop.PropertyType != typeof(String))
{
prop.SetValue(obj, Convert.ChangeType(value, prop.PropertyType), null);
}
else
{
prop.SetValue(obj, value, null);
}
}
return obj;
}
您可以调用它 "old school" 但它有效。
复制 XML(或片段等)并利用 Visual Studio(2015 年(?)和下图是 2017 年)特征 "Paste XML/JSON As Classes"
这对 有效的 XML 有很大帮助 - 特别是对装饰生成的 class 的 "proper" 属性。此外,它只是一个 class,因此您可以根据需要自定义它(同时保留属性)。
对于更复杂的 XML - 例如 namespaces/prefixes,您将非常感激。如果你没有这个工具,你可以使用
XSD.exe
(甚至更老派)——对 XML 文档做同样的事情。从上面的步骤自动生成 类:
...stumbling with the fact they have the same tag name...
别这样。 XML 元素可以重复 - 经常这样做(例如每个网站的
sitemap.xml
)。生成的 class 将帮助您理解它。这是一个标准 collection/array/list.[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)] public partial class configuration { private configurationSetting[] settingField; /// <remarks/> [System.Xml.Serialization.XmlElementAttribute("setting")] public configurationSetting[] setting { get { return this.settingField; } set { this.settingField = value; } } } [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] public partial class configurationSetting { private string valueField; private string nameField; /// <remarks/> public string value { get { return this.valueField; } set { this.valueField = value; } } /// <remarks/> [System.Xml.Serialization.XmlAttributeAttribute()] public string name { get { return this.nameField; } set { this.nameField = value; } } }
鉴于以上情况,您可以这样做:
string rawXml = "<configuration><setting name=\"host\"><value>127.0.0.1</value></setting><setting name=\"port\"><value>80</value></setting></configuration>";
var ser = new XmlSerializer(typeof(configuration));
configuration config;
using (TextReader rdr = new StringReader(rawXml))
{
config = (configuration)ser.Deserialize(rdr);
}
foreach (configurationSetting setting in config.setting)
{
Console.WriteLine($"{setting.name} = {setting.value}");
}
输出:
host = 127.0.0.1
port = 80
Hth..