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

    }

}