在 XSD 生成的对象中设置文本内容

Setting text content in object generated by XSD

我有一个 .dtd 文件已转换为 .xsd 文件。此文件有一个元素标识:

  <xs:element name="Identity">
    <xs:complexType mixed="true">
      <xs:sequence>
        <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##any" />
      </xs:sequence>
      <xs:attribute name="lastChangedTimestamp" type="xs:string" />
    </xs:complexType>
  </xs:element>

这会生成以下示例 xml,其中包含一些文本内容:

<Identity lastChangedTimestamp="lastChangedTimestamp1" xmlns="http://tempuri.org/cXML">text</Identity>

我使用 xsd.exe 将 .xsd 转换为 .cs 文件:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://tempuri.org/cXML")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://tempuri.org/cXML", IsNullable = false)]
public partial class Identity
{
    public string Text { get; set; }
    private System.Xml.XmlNode[] anyField;

    private string lastChangedTimestampField;

    /// <remarks/>
    [System.Xml.Serialization.XmlTextAttribute()]
    [System.Xml.Serialization.XmlAnyElementAttribute()]
    public System.Xml.XmlNode[] Any
    {
        get
        {
            return this.anyField;
        }
        set
        {
            this.anyField = value;
        }
    }

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

但是这不允许我设置身份节点的文本内容:

var credential = new Credential()
{
    Identity = new Identity()
    {
        lastChangedTimestamp = "lastChangedTimestamp1",
        //Text = "MyRef" <- would like to set it at this point
    }
};

有什么我可以做的来确保当我序列化 Identity 对象时我可以将我的 ref 放入节点的文本内容中,或者这是否不受支持?

<Identity lastChangedTimestamp="lastChangedTimestamp1">
    MyRef
</Identity>

最后我更新了 xsd 身份节点以添加 <xs:extension base="xs:string">:

  <xs:element name="Identity">
    <xs:complexType mixed="true">
      <xs:simpleContent>
        <xs:extension base="xs:string">
          <xs:attribute name="lastChangedTimestamp" type="xs:string" />
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

这在我的对象中创建了一个文本数组

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
    [System.SerializableAttribute()]
    [System.Diagnostics.DebuggerStepThroughAttribute()]
    [System.ComponentModel.DesignerCategoryAttribute("code")]
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://tempuri.org/cXML")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "http://tempuri.org/cXML", IsNullable = false)]
    public partial class Identity
    {

        private string lastChangedTimestampField;

        private string[] textField;

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

        /// <remarks/>
        [System.Xml.Serialization.XmlTextAttribute()]
        public string[] Text
        {
            get
            {
                return this.textField;
            }
            set
            {
                this.textField = value;
            }
        }
    }

然后我可以用它来设置我的参考:

new Credential()
{
    Identity = new Identity()
    {
        Text=new string[]
        {
            "MyRef"
        }
    }
}

不确定这是否是最好的方法,但我现在可以使用它。

mixed="true" 在你的 XSD 表示 <Identity> 元素可以包含 mixed content:

An element type has mixed content when elements of that type may contain character data, optionally interspersed with child elements.

此外,子元素不受 XSD 的约束。

xsd.exeXmlSerializer 通过组合 [XmlText] and [XmlAnyElement] 属性支持混合内容。当两个属性都应用于 XmlNode[] 类型的成员时,XML 中包含的所有混合内容都将绑定到该成员。

在这种情况下,您会注意到 xsd.exe 已创建具有这些属性的 public System.Xml.XmlNode[] Any 成员,因此,要将文本 "MyRef" 添加到您的 XML,您需要向此数组添加适当的 XmlText

var identity = new Identity()
{
    lastChangedTimestamp = "lastChangedTimestamp1",
    Any = new XmlNode []
    {
        new XmlDocument().CreateTextNode("MyRef"),
    },
};

演示 fiddle here.

或者,您可以手动将 Any 属性 更改为对象数组,如 Sruly 的 this answer to XmlSerializer - node containing text + xml + text 所示 :

[XmlText(typeof(string))]
[XmlAnyElement]
public object[] Any { get; set; }

然后你就可以将字符串直接添加到数组中了:

var identity = new Identity()
{
    lastChangedTimestamp = "lastChangedTimestamp1",
    Any = new object []
    {
        "MyRef",
    },
};

(对于更复杂的 XML,您仍然需要分配 XmlNode 个对象。)

演示 fiddle #2 here.