Возвращаясь из мира Ruby с легкостью сопоставления XML-to-hash, я с нетерпением жду, чтобы увидеть что-то подобное в С#.
Вот исходный XML:
<whois-resources xmlns:xlink="http://www.w3.org/1999/xlink">
<service name="search"/>
<parameters>
<inverse-lookup/>
<type-filters/>
<flags/>
<query-strings>
<query-string value="....."/>
</query-strings>
<sources/>
</parameters>
<objects>
<object type="inetnum">
<link xlink:type="locator" xlink:href="http://rest.db.ripe.net/ripe/inetnum/....."/>
<source id="ripe"/>
<primary-key>
<attribute name="inetnum" value="....."/>
</primary-key>
<attributes>
<attribute name="inetnum" value="....."/>
<attribute name="netname" value="....."/>
<attribute name="descr" value="....."/>
<attribute name="descr" value="....."/>
<attribute name="country" value="....."/>
<attribute name="admin-c" value="....." referenced-type="person">
<link xlink:type="locator" xlink:href="http://rest.db.ripe.net/ripe/person/....."/>
</attribute>
<attribute name="tech-c" value="....." referenced-type="person">
<link xlink:type="locator" xlink:href="http://rest.db.ripe.net/ripe/person/....."/>
</attribute>
<attribute name="status" value="ASSIGNED PA"/>
<attribute name="mnt-by" value="....." referenced-type="mntner">
<link xlink:type="locator" xlink:href="http://rest.db.ripe.net/ripe/mntner/....."/>
</attribute>
<attribute name="remarks" value="....."/>
<attribute name="remarks" value="....."/>
<attribute name="remarks" value="....."/>
<attribute name="source" value="....." comment="Filtered"/>
</attributes>
<tags>
<tag id="RIPE-USER-RESOURCE"/>
</tags>
</object>
<object type="person">
<link xlink:type="locator" xlink:href="http://rest.db.ripe.net/ripe/person/....."/>
<source id="ripe"/>
<primary-key>
<attribute name="nic-hdl" value="....."/>
</primary-key>
<attributes>
<attribute name="person" value="....."/>
<attribute name="address" value="....."/>
<attribute name="address" value="....."/>
<attribute name="address" value="....."/>
<attribute name="phone" value="....."/>
<attribute name="fax-no" value="....."/>
<attribute name="nic-hdl" value="....."/>
<attribute name="mnt-by" value="....." referenced-type="mntner">
<link xlink:type="locator" xlink:href="http://rest.db.ripe.net/ripe/mntner/....."/>
</attribute>
<attribute name="remarks" value="....."/>
<attribute name="remarks" value="....."/>
<attribute name="remarks" value="....."/>
<attribute name="remarks" value="....."/>
<attribute name="source" value="....." comment="Filtered"/>
</attributes>
</object>
<object type="route">
<link xlink:type="locator" xlink:href="http://rest.db.ripe.net/ripe/route/....."/>
<source id="ripe"/>
<primary-key>
<attribute name="route" value="....."/>
<attribute name="origin" value="....."/>
</primary-key>
<attributes>
<attribute name="route" value="....."/>
<attribute name="descr" value="....."/>
<attribute name="origin" value="....." referenced-type="aut-num">
<link xlink:type="locator" xlink:href="http://rest.db.ripe.net/ripe/aut-num/....."/>
</attribute>
<attribute name="remarks" value="....."/>
<attribute name="remarks" value="....."/>
<attribute name="remarks" value="....."/>
<attribute name="remarks" value="....."/>
<attribute name="mnt-by" value="....." referenced-type="mntner">
<link xlink:type="locator" xlink:href="http://rest.db.ripe.net/ripe/mntner/....."/>
</attribute>
<attribute name="source" value="....." comment="Filtered"/>
</attributes>
</object>
</objects>
<terms-and-conditions xlink:type="locator" xlink:href="http://www.ripe.net/db/support/db-terms-conditions.pdf"/>
</whois-resources>
который я хотел бы переназначить для объекта со следующей структурой:
{
Service: {
Name: "....."
},
Parameters: {
QueryStrings: [".....", "....."]
},
Inetnum: {
Link: {
Type: ".....",
Href: "....."
},
Source: {
id: "....."
},
PrimaryKey: {
Inetnum: "....."
},
Attr: {
Inetnum: ".....",
Netname: ".....",
Descr: ".....",
Country: ".....",
AdminC: {
Value: ".....",
ReferencedType: ".....",
Link: {
Type: ".....",
Href: "....."
}
},
TechC: {
Value: ".....",
ReferencedType: ".....",
Link: {
Type: ".....",
Href: "....."
}
},
Status: ".....",
MntBy: {
Value: ".....",
ReferencedType: ".....",
Link: {
Type: ".....",
Href: "....."
}
}
Remarks: ".....", #a concatenation of all remarks nodes
Source: {
Value: ".....",
Comment: "....."
}
},
Tags: [
{ id: "....." }
]
},
Person {
Link: {
Type: ".....",
Href: "....."
},
Source: {
id: "....."
}
PrimaryKey: {
NicHdl: "....."
},
Attr: {
Person: ".....",
Address: ".....", #a concatenation of all address nodes
Phone: ".....",
FaxNo: ".....",
NicHdl: ".....",
MntBy: {
Value: ".....",
ReferencedType: ".....",
Link: {
Type: ".....",
Href: "....."
}
}
Remarks: ".....", #a concatenation of all remarks nodes
Source: {
Value: ".....",
Comment: "....."
}
}
},
Route: {
Link: {
Type: ".....",
Href: "....."
},
Source: {
id: "....."
},
PrimaryKey: {
Route: ".....",
Origin: "....."
},
Attr: {
Route: ".....",
Descr: ".....",
Origin: {
Value: ".....",
ReferencedType: ".....",
Link: {
Type: ".....",
Href: "....."
}
},
Remarks: ".....", #a concatenation of all remarks nodes
MntBy: {
Value: ".....",
ReferencedType: ".....",
Link: {
Type: ".....",
Href: "....."
}
},
Source: {
Value: ".....",
Comment: "....."
}
}
},
TermsAndConditions: {
Type: ".....",
Href: "....."
}
}
чтобы иметь возможность вызвать такие свойства, как:
whois.Inetnum.Attr.Netname
Мне совершенно не нравится идея извлекать каждый узел, вызывая SelectSingleNode("xpath");
Желаемый процесс:
Вот как это сделать.
Сначала вам нужно добавить соответствующие ссылки (здесь несколько):
using System.Linq;
using System.Xml.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
Создайте класс-оболочку, в котором будут храниться десериализованные данные.
[XmlRoot("root")]
public class root
{
[XmlElement("MyObject")]
public List<MyObject> A_Object
{
get;
set;
}
}
Затем класс, который будет содержать десериализованные данные, например здесь MyObject:
public class MyObject {
[XmlElement("type")] //from your sample code route,person all go here
public string objType
{
get;
set;
}
[XmlElement("address")]
public string personAddr
{
get;
set;
}
[XmlElement("phone")]
public string personPhone
{
get;
set;
}
}
* Примечание: если у вас есть свойства, которые вы хотите отслеживать, но не быть десериализованными, у вас могут быть свойства, которые не имеют [XmlElement].
public List<myObject> DeserializeXML(string xmlPath) { XmlSerializer deserializer = new XmlSerializer(typeof(root)); List<myObject> objectList = new List<myObject>(); try { using (TextReader textReader = new StreamReader(xmlPath)) { root setOfObjects; setOfObjects = (root)deserializer.Deserialize(textReader); } objectList = setOfObjects.A_Object; } catch(FileNotFoundException a) { } return objectList; }
public List<myObject> DeserializeXML(string xmlPath) { XmlSerializer deserializer = new XmlSerializer(typeof(root)); List<myObject> objectList = new List<myObject>(); try { using (TextReader textReader = new StreamReader(xmlPath)) { root setOfObjects; setOfObjects = (root)deserializer.Deserialize(textReader); } objectList = setOfObjects.A_Object; } catch(FileNotFoundException a) { } return objectList; }
5. Затем вы можете продолжить и манипулировать им в любой форме, какой вам нравится, может быть, снова сериализуйте ее по-другому.
XmlSerializer
?