XSD 描述用于解析为 C# 对象的网页
XSD to describe a web page for parsing into C# objects
我正在致力于使用 Selenium 与网站进行自动化交互。为了避免为网站本身定义复杂的 classes,我认为最好有 XML 文档来描述我可以序列化为 C# 对象并进行必要交互的网站。
我有一个名为 Element 的基础 class,它是所有对象(网站、页面和页面上的项目,如按钮和文本框)的基础:
public class Element
{
public string Name { get; set; }
public string Id { get; set; }
public string XPath { get; set; }
public Element Parent { get; set; }
public Collection<Element> Children { get; set; }
}
我希望我的 XML 文件看起来像这样:
<?xml version="1.0" encoding="utf-8" ?>
<Site>
<Name>MyTestSite</Name>
<Url>http://mytesturl</Url>
<Children>
<Page>
<Address>HomePage</Address>
<Children>
<Button>
<Name>SomeButton</Name>
<Id>SomeID</Id>
<XPath>SomePath</XPath>
<Enabled>True</Enabled>
<Action>OpenLoginDialog</Action>
</Button>
<Dialog>
<Name>LoginPopUpDialog</Name>
<Children>
<StaticText>
<Name>LoginSuccessMessage</Name>
<Id>SomeID</Id>
<XPath>SomePath</XPath>
<Value>Hello</Value>
</StaticText>
<Button>
<Name>OkButton</Name>
<Value>SomeString</Value>
<Id>SomeID</Id>
<XPath>SomePath</XPath>
<Action>DialogDismiss</Action>
</Button>
</Children>
</Dialog>
<CheckBox>
<Name>SomeCheckBox</Name>
<Id>SomeID</Id>
<XPath>SomePath</XPath>
<Enabled>True</Enabled>
<Checked>True</Checked>
</CheckBox>
</Children>
</Page>
</Children>
</Site>
我的理解是,我必须为要放入文档中的节点创建复杂类型,例如页面、对话框、按钮等。所以我声明了一个 Element 复杂类型并将其用作其他类型的基础:
<xs:complexType name="Element">
<xs:sequence>
<xs:element type="xs:string" name="Name"/>
<xs:element type="xs:string" name="Id"/>
<xs:element type="xs:string" name="XPath"/>
<xs:element maxOccurs="unbounded" name="Children">
<xs:complexType>
<xs:sequence minOccurs="0">
<xs:element ref="Element" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Site">
<xs:complexContent>
<xs:extension base="Element">
<xs:sequence>
<xs:element type="xs:string" name="Url"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Page">
<xs:complexContent>
<xs:extension base="Element">
<xs:sequence>
<xs:element type="xs:string" name="Address"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
但是当我尝试序列化它时,唯一被初始化的对象是站点。我做错了什么?
请注意:XSD 文件与您面临的问题完全没有关系。因为 XSD 文件只是为了验证 xml 文件(是否遵守您定义的某些规则)。
问题出在您的 C# 代码中。因为 XmlSerializer class 负责序列化/反序列化对象 to/from xml 标签。
我认为您缺少 "Childern" 属性 和 "Element" class 中的 "Parent" 属性 的一些属性,请尝试以下
public class Element
{
public string Name { get; set; }
public string Id { get; set; }
public string XPath { get; set; }
[XmlElement(ElementName="TextBox", Type = typeof(TextBox))]
[XmlElement(ElementName="Page", Type = typeof(Page))]
[XmlElement(ElementName="Button", Type = typeof(Button))]
[XmlElement(ElementName="Dialog", Type = typeof(Dialog))]
public Element Parent { get; set; }
[XmlArray("Children", IsNullable = false)]
[XmlArrayItem(Type = typeof(TextBox))]
[XmlArrayItem(Type = typeof(Page))]
[XmlArrayItem(Type = typeof(Button))]
[XmlArrayItem(Type = typeof(Dialog))]
public Collection<Element> Children { get; set; }
}
注意:
1- 您必须为 "Element" 基础 class 的每个子 class 添加 "Children" 属性 上的 [XmlArrayItem] 属性,以使 "XmlSerializer"能够应付。
2- 您必须在 "Parent" 属性 上添加 [XmlElement] 属性,对于 "Element" 基础 class 的每个子 class "XmlSerializer" 能应付。
如果您有任何问题,请告诉我。
干杯
试试这个
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
Site site = new Site()
{
name = "MyTestSite",
url = "http://mytesturl",
children = new Children()
{
page = new Page()
{
address = "HomePage",
children = new Children()
{
button = new Button()
{
name = "SomeButton",
id = "SomeID",
xPath = "SomePath",
enabled = true,
action = "OpenLoginDialog"
},
dialog = new Dialog()
{
name = "LoginPopUpDialog",
children = new Children()
{
staticText = new StaticText()
{
name = "LoginSuccessMessage",
id = "SomeID",
xPath = "SomePath",
value = "Hello"
},
button = new Button()
{
name = "OkButton",
value = "SomeString",
id = "SomeID",
xPath = "SomePath",
action = "DialogDismiss"
}
}
},
checkBox = new CheckBox()
{
name = "SomeCheckBox",
id = "SomeID",
xPath = "SomePath",
enabled = true,
m_checked = true
}
}
}
}
};
XmlSerializer serializer = new XmlSerializer(typeof(Site));
StreamWriter writer = new StreamWriter(FILENAME);
serializer.Serialize(writer, site);
writer.Flush();
writer.Close();
writer.Dispose();
XmlSerializer xs = new XmlSerializer(typeof(Site));
XmlTextReader reader = new XmlTextReader(FILENAME);
Site newSite = (Site)xs.Deserialize(reader);
}
}
[XmlRoot("Site")]
public class Site
{
[XmlElement("Children")]
public Children children { get; set; }
[XmlElement("Name")]
public string name { get; set; }
[XmlElement("Url")]
public string url { get; set; }
}
[XmlRoot("Children")]
public class Children
{
[XmlElement("Page")]
public Page page { get; set; }
[XmlElement("Button")]
public Button button { get; set; }
[XmlElement("Dialog")]
public Dialog dialog { get; set; }
[XmlElement("CheckBox")]
public CheckBox checkBox { get; set; }
[XmlElement("StaticText")]
public StaticText staticText { get; set; }
}
[XmlRoot("Page")]
public class Page
{
[XmlElement("Address")]
public string address { get; set; }
[XmlElement("Children")]
public Children children { get; set; }
}
[XmlRoot("Button")]
public class Button
{
[XmlElement("Name")]
public string name { get; set; }
[XmlElement("Value")]
public string value { get; set; }
[XmlElement("Id")]
public string id { get; set; }
[XmlElement("XPath")]
public string xPath { get; set; }
[XmlElement("DialogDismiss")]
public string dialogDismiss { get; set; }
[XmlElement("Enabled")]
public Boolean enabled { get; set; }
[XmlElement("Action")]
public string action { get; set; }
}
[XmlRoot("Dialog")]
public class Dialog
{
[XmlElement("Name")]
public string name { get; set; }
[XmlElement("Children")]
public Children children { get; set; }
}
[XmlRoot("CheckBox")]
public class CheckBox
{
[XmlElement("Name")]
public string name { get; set; }
[XmlElement("Id")]
public string id { get; set; }
[XmlElement("XPath")]
public string xPath { get; set; }
[XmlElement("Enabled")]
public Boolean enabled { get; set; }
[XmlElement("Checked")]
public Boolean m_checked { get; set; }
}
[XmlRoot("StaticText")]
public class StaticText
{
[XmlElement("Name")]
public string name { get; set; }
[XmlElement("Id")]
public string id { get; set; }
[XmlElement("XPath")]
public string xPath { get; set; }
[XmlElement("Value")]
public string value { get; set; }
}
}
我正在致力于使用 Selenium 与网站进行自动化交互。为了避免为网站本身定义复杂的 classes,我认为最好有 XML 文档来描述我可以序列化为 C# 对象并进行必要交互的网站。
我有一个名为 Element 的基础 class,它是所有对象(网站、页面和页面上的项目,如按钮和文本框)的基础:
public class Element
{
public string Name { get; set; }
public string Id { get; set; }
public string XPath { get; set; }
public Element Parent { get; set; }
public Collection<Element> Children { get; set; }
}
我希望我的 XML 文件看起来像这样:
<?xml version="1.0" encoding="utf-8" ?>
<Site>
<Name>MyTestSite</Name>
<Url>http://mytesturl</Url>
<Children>
<Page>
<Address>HomePage</Address>
<Children>
<Button>
<Name>SomeButton</Name>
<Id>SomeID</Id>
<XPath>SomePath</XPath>
<Enabled>True</Enabled>
<Action>OpenLoginDialog</Action>
</Button>
<Dialog>
<Name>LoginPopUpDialog</Name>
<Children>
<StaticText>
<Name>LoginSuccessMessage</Name>
<Id>SomeID</Id>
<XPath>SomePath</XPath>
<Value>Hello</Value>
</StaticText>
<Button>
<Name>OkButton</Name>
<Value>SomeString</Value>
<Id>SomeID</Id>
<XPath>SomePath</XPath>
<Action>DialogDismiss</Action>
</Button>
</Children>
</Dialog>
<CheckBox>
<Name>SomeCheckBox</Name>
<Id>SomeID</Id>
<XPath>SomePath</XPath>
<Enabled>True</Enabled>
<Checked>True</Checked>
</CheckBox>
</Children>
</Page>
</Children>
</Site>
我的理解是,我必须为要放入文档中的节点创建复杂类型,例如页面、对话框、按钮等。所以我声明了一个 Element 复杂类型并将其用作其他类型的基础:
<xs:complexType name="Element">
<xs:sequence>
<xs:element type="xs:string" name="Name"/>
<xs:element type="xs:string" name="Id"/>
<xs:element type="xs:string" name="XPath"/>
<xs:element maxOccurs="unbounded" name="Children">
<xs:complexType>
<xs:sequence minOccurs="0">
<xs:element ref="Element" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="Site">
<xs:complexContent>
<xs:extension base="Element">
<xs:sequence>
<xs:element type="xs:string" name="Url"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Page">
<xs:complexContent>
<xs:extension base="Element">
<xs:sequence>
<xs:element type="xs:string" name="Address"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
但是当我尝试序列化它时,唯一被初始化的对象是站点。我做错了什么?
请注意:XSD 文件与您面临的问题完全没有关系。因为 XSD 文件只是为了验证 xml 文件(是否遵守您定义的某些规则)。
问题出在您的 C# 代码中。因为 XmlSerializer class 负责序列化/反序列化对象 to/from xml 标签。
我认为您缺少 "Childern" 属性 和 "Element" class 中的 "Parent" 属性 的一些属性,请尝试以下
public class Element
{
public string Name { get; set; }
public string Id { get; set; }
public string XPath { get; set; }
[XmlElement(ElementName="TextBox", Type = typeof(TextBox))]
[XmlElement(ElementName="Page", Type = typeof(Page))]
[XmlElement(ElementName="Button", Type = typeof(Button))]
[XmlElement(ElementName="Dialog", Type = typeof(Dialog))]
public Element Parent { get; set; }
[XmlArray("Children", IsNullable = false)]
[XmlArrayItem(Type = typeof(TextBox))]
[XmlArrayItem(Type = typeof(Page))]
[XmlArrayItem(Type = typeof(Button))]
[XmlArrayItem(Type = typeof(Dialog))]
public Collection<Element> Children { get; set; }
}
注意: 1- 您必须为 "Element" 基础 class 的每个子 class 添加 "Children" 属性 上的 [XmlArrayItem] 属性,以使 "XmlSerializer"能够应付。
2- 您必须在 "Parent" 属性 上添加 [XmlElement] 属性,对于 "Element" 基础 class 的每个子 class "XmlSerializer" 能应付。
如果您有任何问题,请告诉我。
干杯
试试这个
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
Site site = new Site()
{
name = "MyTestSite",
url = "http://mytesturl",
children = new Children()
{
page = new Page()
{
address = "HomePage",
children = new Children()
{
button = new Button()
{
name = "SomeButton",
id = "SomeID",
xPath = "SomePath",
enabled = true,
action = "OpenLoginDialog"
},
dialog = new Dialog()
{
name = "LoginPopUpDialog",
children = new Children()
{
staticText = new StaticText()
{
name = "LoginSuccessMessage",
id = "SomeID",
xPath = "SomePath",
value = "Hello"
},
button = new Button()
{
name = "OkButton",
value = "SomeString",
id = "SomeID",
xPath = "SomePath",
action = "DialogDismiss"
}
}
},
checkBox = new CheckBox()
{
name = "SomeCheckBox",
id = "SomeID",
xPath = "SomePath",
enabled = true,
m_checked = true
}
}
}
}
};
XmlSerializer serializer = new XmlSerializer(typeof(Site));
StreamWriter writer = new StreamWriter(FILENAME);
serializer.Serialize(writer, site);
writer.Flush();
writer.Close();
writer.Dispose();
XmlSerializer xs = new XmlSerializer(typeof(Site));
XmlTextReader reader = new XmlTextReader(FILENAME);
Site newSite = (Site)xs.Deserialize(reader);
}
}
[XmlRoot("Site")]
public class Site
{
[XmlElement("Children")]
public Children children { get; set; }
[XmlElement("Name")]
public string name { get; set; }
[XmlElement("Url")]
public string url { get; set; }
}
[XmlRoot("Children")]
public class Children
{
[XmlElement("Page")]
public Page page { get; set; }
[XmlElement("Button")]
public Button button { get; set; }
[XmlElement("Dialog")]
public Dialog dialog { get; set; }
[XmlElement("CheckBox")]
public CheckBox checkBox { get; set; }
[XmlElement("StaticText")]
public StaticText staticText { get; set; }
}
[XmlRoot("Page")]
public class Page
{
[XmlElement("Address")]
public string address { get; set; }
[XmlElement("Children")]
public Children children { get; set; }
}
[XmlRoot("Button")]
public class Button
{
[XmlElement("Name")]
public string name { get; set; }
[XmlElement("Value")]
public string value { get; set; }
[XmlElement("Id")]
public string id { get; set; }
[XmlElement("XPath")]
public string xPath { get; set; }
[XmlElement("DialogDismiss")]
public string dialogDismiss { get; set; }
[XmlElement("Enabled")]
public Boolean enabled { get; set; }
[XmlElement("Action")]
public string action { get; set; }
}
[XmlRoot("Dialog")]
public class Dialog
{
[XmlElement("Name")]
public string name { get; set; }
[XmlElement("Children")]
public Children children { get; set; }
}
[XmlRoot("CheckBox")]
public class CheckBox
{
[XmlElement("Name")]
public string name { get; set; }
[XmlElement("Id")]
public string id { get; set; }
[XmlElement("XPath")]
public string xPath { get; set; }
[XmlElement("Enabled")]
public Boolean enabled { get; set; }
[XmlElement("Checked")]
public Boolean m_checked { get; set; }
}
[XmlRoot("StaticText")]
public class StaticText
{
[XmlElement("Name")]
public string name { get; set; }
[XmlElement("Id")]
public string id { get; set; }
[XmlElement("XPath")]
public string xPath { get; set; }
[XmlElement("Value")]
public string value { get; set; }
}
}