我需要为元素实现可序列化类型,该元素包含具有类似XPath表达式的任何元素的序列。 它有非常简单的方案:

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

有没有办法为每个可能的XmlReader实现GetNamespacesInScope 或者也许有另一种解决方案?

===============>>#1 票数:3

我使用这样的代码:

        XPathDocument doc = new XPathDocument("catalog.xml");
        XPathNavigator nav = doc.CreateNavigator();
        var v = nav.GetNamespacesInScope(XmlNamespaceScope.All);

希望它有所帮助,Radu

===============>>#2 票数:1

但是,您可能需要命名空间管理器 - 例如:

XmlElement el = ...; //TODO
XmlNamespaceManager nsmgr = new XmlNamespaceManager(
    el.OwnerDocument.NameTable);
nsmgr.AddNamespace("x", el.OwnerDocument.DocumentElement.NamespaceURI);
var nodes = el.SelectNodes(@"/x:outerelement/x:innerelement", nsmgr);

  ask by andrey.ko translate from so

未解决问题?本站智能推荐: