我需要爲元素實現可序列化的類型,其中包含具有類似XPath表達式的任何元素的序列。 這是一個非常簡單的方案:如何從XmlReader獲得範圍內的命名空間
<xsd:complexType name="FilterType">
<xsd:sequence>
<xsd:any minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
語義元素濃縮於WSBaseNotification話題4.2描述。 問題是,爲了解釋表達式,我們需要一些機制來解析在其中使用的前綴(XmlReader通過LookupNamespace提供這樣的功能)。但還有另一個問題,現階段不可能解析表達,我們現在甚至不能對錶情類型和方言做出任何假設。所以我們需要以某種方式收集該範圍內的所有已定義的前綴。某些XmlReader
-s(例如XmlTextReader
)實現了接口IXmlNamespaceResolver
,它們通過GetNamespacesInScope提供了此類功能,但其中很多都沒有(例如XmlMtomReader
)。這種類型在許多Web服務請求中使用,Web服務使用wcf框架並有幾個綁定,所以我們不能對使用什麼XmlReader
做任何假設。 這裏是原型實現這種類型的,如果我們有XmlReader
GetNamespacesInScope
:
[Serializable]
public class FilterType : IXmlSerializable {
public XElement[] Any;
public void ReadXml(XmlReader reader) {
var xelist = new LinkedList<XElement>();
reader.Read();
var dr = reader as XmlDictionaryReader;
var gns = reader.GetNamespacesInScope(); // need to implement
while (reader.NodeType != XmlNodeType.EndElement) {
if (reader.NodeType == XmlNodeType.Element) {
var x = XElement.ReadFrom(reader) as XElement;
foreach (var ns in gns) {
var pref = ns.Key;
var uri = ns.Value;
if (x.GetNamespaceOfPrefix(pref) == null) {
x.Add(new XAttribute(XName.Get(pref, "http://www.w3.org/2000/xmlns/"), uri));
}
}
xelist.AddLast((XElement)x);
} else {
reader.Skip();
}
}
Any = xelist.ToArray();
reader.ReadEndElement();
}
public void WriteXml(XmlWriter writer) {
if (Any != null) {
foreach (var x in Any) {
x.WriteTo(writer);
}
}
}
public XmlSchema GetSchema() {
return null;
}
}
有什麼辦法來實現GetNamespacesInScope
每一個可能的XmlReader
?或者也許有另一種解決方案?
你在創建它的地方「接收」xmlreader--給你選擇將它包裝在一個傳遞閱讀器中,該閱讀器跟蹤名稱空間並將包裝器傳遞給將使用它的東西? –
在我的理解中,一個WCF編碼元素負責創建xmlreader,它可以是不同的,當前服務使用兩個編碼TextMessageEncoding和MtomMessageEncoding,第一個使用XmlUTF8TextReader,第二個使用XmlMtomReader(使用.net 4.0),但是沒有保證行爲將來不會改變,例如在.net 4.5中。在我看來,爲了控制創建xmlreader,我們需要重寫整個編碼綁定元素,在我看來,這是一項非常複雜的任務。 –