我有一些严重的问题反序列化xml文档。我不负责结构,因此根本不能进行任何修改(仅在运行时删除/替换一些静态内容)。
该文档包含一些具有模块深度的查询构建器的条件。
首先,这是一个可以由外部应用程序生成的示例XML文件。它的结构取决于条件的复杂程度。
这是一个简单的例子:
XML简单
<?xml version="1.0"?>
<QueryBuilderSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://dev.somecompany.com/settings/web/querybuilder">
<Root>
<Operation>And</Operation>
<Conditions xsi:type="Condition">
<DBName>BELEG_NR_</DBName>
<Provider xsi:type="TextConditionProvider">
<Operation>Contains</Operation>
<Value>LC</Value>
<SystemFunction>None</SystemFunction>
</Provider>
</Conditions>
</Root>
</QueryBuilderSettings>
这是一个复杂的问题:
XML complex
<?xml version="1.0"?>
<QueryBuilderSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://dev.somecompany.com/settings/web/querybuilder">
<Root>
<Operation>And</Operation>
<Conditions xsi:type="Condition">
<DBName>INVOICEID</DBName>
<Provider xsi:type="TextConditionProvider">
<Operation>Contains</Operation>
<Value>LC</Value>
<SystemFunction>None</SystemFunction>
</Provider>
</Conditions>
<Conditions xsi:type="Condition">
<DBName>DEPARTMENT</DBName>
<Provider xsi:type="TextConditionProvider">
<Operation>Equal</Operation>
<Value>Lager</Value>
<SystemFunction>None</SystemFunction>
</Provider>
</Conditions>
<Conditions xsi:type="GroupCondition">
<Operation>Or</Operation>
<Conditions xsi:type="Condition">
<DBName>STATEFIELD_1</DBName>
<Provider xsi:type="TextConditionProvider">
<Operation>NotEqual</Operation>
<Value>TEST</Value>
<SystemFunction>None</SystemFunction>
</Provider>
</Conditions>
<Conditions xsi:type="Condition">
<DBName>STATEFIELD_2</DBName>
<Provider xsi:type="EmptyConditionProvider">
<Operation>Empty</Operation>
</Provider>
</Conditions>
<Conditions xsi:type="GroupCondition">
<Operation>Or</Operation>
<Conditions xsi:type="Condition">
<DBName>DEPARTMENT</DBName>
<Provider xsi:type="EmptyConditionProvider">
<Operation>NotEmpty</Operation>
</Provider>
</Conditions>
<Conditions xsi:type="Condition">
<DBName>INVOICEDATE</DBName>
<Provider xsi:type="DateConditionProvider">
<Operation>Equal</Operation>
<Value>2018-03-01T00:00:00Z</Value>
<SystemFunction>None</SystemFunction>
</Provider>
</Conditions>
<Conditions xsi:type="GroupCondition">
<Operation>Or</Operation>
<Conditions xsi:type="Condition">
<DBName>INVOICEDATE</DBName>
<Provider xsi:type="DateConditionProvider">
<Operation>NotEqual</Operation>
<Value>2018-03-02T00:00:00Z</Value>
<SystemFunction>None</SystemFunction>
</Provider>
</Conditions>
<Conditions xsi:type="Condition">
<DBName>CUSTOMERID</DBName>
<Provider xsi:type="RangeNumericConditionProvider">
<Operation>Range</Operation>
<FromValue>0</FromValue>
<ToValue>12000</ToValue>
</Provider>
</Conditions>
</Conditions>
</Conditions>
</Conditions>
</Root>
</QueryBuilderSettings>
XSD生成以下输出(复杂的):
XSD
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="QueryBuilderSettings" targetNamespace="http://dev.somecompany.com/settings/web/querybuilder" xmlns:mstns="http://dev.somecompany.com/settings/web/querybuilder" xmlns="http://dev.somecompany.com/settings/web/querybuilder" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified">
<xs:element name="Conditions">
<xs:complexType>
<xs:sequence>
<xs:element name="Operation" type="xs:string" minOccurs="0" />
<xs:element name="DBName" type="xs:string" minOccurs="0" />
<xs:element name="Provider" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Operation" type="xs:string" minOccurs="0" />
<xs:element name="FromValue" type="xs:string" minOccurs="0" />
<xs:element name="ToValue" type="xs:string" minOccurs="0" />
<xs:element name="Value" type="xs:string" minOccurs="0" />
<xs:element name="Period" type="xs:string" minOccurs="0" />
<xs:element name="SystemFunction" type="xs:string" minOccurs="0" />
<xs:element name="AddWildcard" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element ref="Conditions" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="QueryBuilderSettings" msdata:IsDataSet="true" msdata:Locale="en-US">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="Conditions" />
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element name="Operation" type="xs:string" minOccurs="0" />
<xs:element ref="Conditions" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
这是为xsd-file
生成的cs-classMODEL
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class Conditions {
private string operationField;
private string dBNameField;
private ConditionsProvider[] providerField;
private Conditions[] conditions1Field;
/// <remarks/>
public string Operation {
get {
return this.operationField;
}
set {
this.operationField = value;
}
}
/// <remarks/>
public string DBName {
get {
return this.dBNameField;
}
set {
this.dBNameField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Provider")]
public ConditionsProvider[] Provider {
get {
return this.providerField;
}
set {
this.providerField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Conditions")]
public Conditions[] Conditions1 {
get {
return this.conditions1Field;
}
set {
this.conditions1Field = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class ConditionsProvider {
private string operationField;
private string fromValueField;
private string toValueField;
private string valueField;
private string periodField;
private string systemFunctionField;
private string addWildcardField;
/// <remarks/>
public string Operation {
get {
return this.operationField;
}
set {
this.operationField = value;
}
}
/// <remarks/>
public string FromValue {
get {
return this.fromValueField;
}
set {
this.fromValueField = value;
}
}
/// <remarks/>
public string ToValue {
get {
return this.toValueField;
}
set {
this.toValueField = value;
}
}
/// <remarks/>
public string Value {
get {
return this.valueField;
}
set {
this.valueField = value;
}
}
/// <remarks/>
public string Period {
get {
return this.periodField;
}
set {
this.periodField = value;
}
}
/// <remarks/>
public string SystemFunction {
get {
return this.systemFunctionField;
}
set {
this.systemFunctionField = value;
}
}
/// <remarks/>
public string AddWildcard {
get {
return this.addWildcardField;
}
set {
this.addWildcardField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class QueryBuilderSettings {
private object[] itemsField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Conditions", typeof(Conditions))]
[System.Xml.Serialization.XmlElementAttribute("Root", typeof(QueryBuilderSettingsRoot))]
public object[] Items {
get {
return this.itemsField;
}
set {
this.itemsField = value;
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class QueryBuilderSettingsRoot {
private string operationField;
private Conditions[] conditionsField;
/// <remarks/>
public string Operation {
get {
return this.operationField;
}
set {
this.operationField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Conditions")]
public Conditions[] Conditions {
get {
return this.conditionsField;
}
set {
this.conditionsField = value;
}
}
}
到目前为止,这里没有问题。
所以基本上我将它反序列化为:
var qbs = prlm.ExtendedStatement?.Replace(@" xmlns=""http://dev.somecompany.com/settings/web/querybuilder""", ""); // replace because of error, see post below
var deserializer = new XmlSerializer(typeof(QueryBuilderSettings));
var xmlDoc = new XmlDocument();
if (string.IsNullOrEmpty(qbs)) return null;
xmlDoc.LoadXml(qbs);
using (XmlReader reader = new XmlNodeReader(xmlDoc))
{
var obj = (QueryBuilderSettings)deserializer.Deserialize(reader); // EXCEPTION occurs here
...
}
如果我尝试反序列化原始的xml文件,我会收到以下错误:
<QueryBuilderSettings xmlns='http://dev.somecompany.com/settings/web/querybuilder'> was not expected
好的,没问题。我只是在运行时删除它。现在我收到以下错误:
The same table 'Conditions' cannot be the child table in two nested relations.
妈的,但是我看到这里发生了什么。所以我认为这将是一个很好的&#39;想要从
更改xsd文件msdata:IsDataSet="true"
到
msdata:IsDataSet="false"
会导致以下错误:
The specified type was not recognized: Name='Condition', Namespace='', at <Conditions xmlns=''>
我从来没有这样的问题,幸运的是,所以我不知道如何解决这个问题,生成一个类模型,我可以在运行时轻松使用(如果可能的话,我会避免使用数据集/表) )。
希望你们中的任何人都可以帮助我并指出正确的方向,因为我现在没有想法。
提前致谢。