在 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.exe
和 XmlSerializer
通过组合 [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.
我有一个 .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.exe
和 XmlSerializer
通过组合 [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.