188 lines
7.2 KiB
C#
188 lines
7.2 KiB
C#
|
//------------------------------------------------------------------------------
|
||
|
// <copyright file="XmlQualifiedNameTest.cs" company="Microsoft">
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
// </copyright>
|
||
|
// <owner current="true" primary="true">[....]</owner>
|
||
|
//------------------------------------------------------------------------------
|
||
|
|
||
|
using System;
|
||
|
using System.Xml;
|
||
|
using System.Xml.Schema;
|
||
|
using System.Collections.Generic;
|
||
|
using System.Diagnostics;
|
||
|
using System.Text;
|
||
|
|
||
|
namespace System.Xml.Xsl {
|
||
|
|
||
|
/// <summary>
|
||
|
/// XmlQualifiedName extends XmlQualifiedName to support wildcards and adds nametest functionality
|
||
|
/// Following are the examples:
|
||
|
/// {A}:B XmlQualifiedNameTest.New("B", "A") Match QName with namespace A and local name B
|
||
|
/// * XmlQualifiedNameTest.New(null, null) Match any QName
|
||
|
/// {A}:* XmlQualifiedNameTest.New(null, "A") Match QName with namespace A and any local name
|
||
|
/// XmlQualifiedNameTest.New("A", false)
|
||
|
/// *:B XmlQualifiedNameTest.New("B", null) Match QName with any namespace and local name B
|
||
|
/// ~{A}:* XmlQualifiedNameTest.New("B", "A") Match QName with namespace not A and any local name
|
||
|
/// {~A}:B only as a result of the intersection Match QName with namespace not A and local name B
|
||
|
/// </summary>
|
||
|
internal class XmlQualifiedNameTest : XmlQualifiedName {
|
||
|
bool exclude;
|
||
|
const string wildcard = "*";
|
||
|
static XmlQualifiedNameTest wc = XmlQualifiedNameTest.New(wildcard, wildcard);
|
||
|
|
||
|
/// <summary>
|
||
|
/// Full wildcard
|
||
|
/// </summary>
|
||
|
public static XmlQualifiedNameTest Wildcard {
|
||
|
get { return wc; }
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Constructor
|
||
|
/// </summary>
|
||
|
private XmlQualifiedNameTest(string name, string ns, bool exclude) : base (name, ns) {
|
||
|
this.exclude = exclude;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Construct new from name and namespace. Returns singleton Wildcard in case full wildcard
|
||
|
/// </summary>
|
||
|
public static XmlQualifiedNameTest New(string name, string ns) {
|
||
|
if (ns == null && name == null) {
|
||
|
return Wildcard;
|
||
|
}
|
||
|
else {
|
||
|
return new XmlQualifiedNameTest(name == null ? wildcard : name, ns == null ? wildcard : ns, false);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// True if matches any name and any namespace
|
||
|
/// </summary>
|
||
|
public bool IsWildcard {
|
||
|
get { return (object)this == (object)Wildcard; }
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// True if matches any name
|
||
|
/// </summary>
|
||
|
public bool IsNameWildcard {
|
||
|
get { return (object)this.Name == (object)wildcard; }
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// True if matches any namespace
|
||
|
/// </summary>
|
||
|
public bool IsNamespaceWildcard {
|
||
|
get { return (object)this.Namespace == (object)wildcard; }
|
||
|
}
|
||
|
|
||
|
private bool IsNameSubsetOf(XmlQualifiedNameTest other) {
|
||
|
return other.IsNameWildcard || this.Name == other.Name;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
private bool IsNamespaceSubsetOf(XmlQualifiedNameTest other) {
|
||
|
return other.IsNamespaceWildcard
|
||
|
|| (this.exclude == other.exclude && this.Namespace == other.Namespace)
|
||
|
|| (other.exclude && !this.exclude && this.Namespace != other.Namespace);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// True if this matches every QName other does
|
||
|
/// </summary>
|
||
|
public bool IsSubsetOf(XmlQualifiedNameTest other) {
|
||
|
return IsNameSubsetOf(other) && IsNamespaceSubsetOf(other);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Return true if the result of intersection with other is not empty
|
||
|
/// </summary>
|
||
|
public bool HasIntersection(XmlQualifiedNameTest other) {
|
||
|
return (IsNamespaceSubsetOf(other) || other.IsNamespaceSubsetOf(this)) && (IsNameSubsetOf(other) || other.IsNameSubsetOf(this));
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// String representation
|
||
|
/// </summary>
|
||
|
public override string ToString() {
|
||
|
if ((object)this == (object)Wildcard) {
|
||
|
return "*";
|
||
|
}
|
||
|
else {
|
||
|
if (this.Namespace.Length == 0) {
|
||
|
return this.Name;
|
||
|
}
|
||
|
else if ((object)this.Namespace == (object)wildcard) {
|
||
|
return "*:" + this.Name;
|
||
|
}
|
||
|
else if (this.exclude) {
|
||
|
return "{~" + this.Namespace + "}:" + this.Name;
|
||
|
}
|
||
|
else {
|
||
|
return "{" + this.Namespace + "}:" + this.Name;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#if SchemaTypeImport
|
||
|
/// <summary>
|
||
|
/// Construct new from XmlQualifiedName. Returns singleton Wildcard in case full wildcard
|
||
|
/// </summary>
|
||
|
public static XmlQualifiedNameTest New(XmlQualifiedName name) {
|
||
|
if (name.IsEmpty) {
|
||
|
return Wildcard;
|
||
|
}
|
||
|
else {
|
||
|
return new XmlQualifiedNameTest(name.Name, name.Namespace, false);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Construct new "exclusion" name test
|
||
|
/// </summary>
|
||
|
public static XmlQualifiedNameTest New(string ns, bool exclude) {
|
||
|
Debug.Assert(ns != null);
|
||
|
return new XmlQualifiedNameTest(wildcard, ns, exclude);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Return the result of intersection with other
|
||
|
/// </summary>
|
||
|
public XmlQualifiedNameTest Intersect(XmlQualifiedNameTest other) {
|
||
|
// Namespace
|
||
|
// this\other ~y * y
|
||
|
// ~x x=y ? this|other : null this x!=y ? other : null
|
||
|
// * other this|other other
|
||
|
// x x!=y ? this : null this x=y ? this|other : null
|
||
|
XmlQualifiedNameTest namespaceFrom = IsNamespaceSubsetOf(other) ? this : other.IsNamespaceSubsetOf(this) ? other : null;
|
||
|
XmlQualifiedNameTest nameFrom = IsNameSubsetOf(other) ? this : other.IsNameSubsetOf(this) ? other : null;
|
||
|
|
||
|
if ((object)namespaceFrom == (object)nameFrom) {
|
||
|
return namespaceFrom;
|
||
|
}
|
||
|
else if (namespaceFrom == null || nameFrom == null) {
|
||
|
return null;
|
||
|
}
|
||
|
else {
|
||
|
return new XmlQualifiedNameTest(nameFrom.Name, namespaceFrom.Namespace, namespaceFrom.ExcludeNamespace);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// True if neither name nor namespace is a wildcard
|
||
|
/// </summary>
|
||
|
public bool IsSingleName {
|
||
|
get { return (object)this.Name != (object)wildcard && (object)this.Namespace != (object)wildcard && this.exclude == false; }
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// True if matches any namespace other then this.Namespace
|
||
|
/// </summary>
|
||
|
public bool ExcludeNamespace {
|
||
|
get { return this.exclude; }
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
}
|