public string GetValue(XElement element, XmlNamespaceManager nsm) { XPathContext context = new XPathContext((NameTable)nsm.NameTable); XPathNavigator navigator = element.CreateNavigator(); object result = null; foreach (var ns in nsm.GetNamespacesInScope(XmlNamespaceScope.All)) context.AddNamespace(ns.Key, ns.Value); context.Arguments.AddParam(XPathContext.ParameterNames.CurrentNode, string.Empty, navigator.Select(".")); result = navigator.Evaluate(this.RawValue, context); if (result is string) return (string)result; else if (result is XPathNodeIterator) { var iterator = ((XPathNodeIterator)result); var current = (XPathNavigator)((IEnumerable)iterator).Cast<object>().First(); return current.Value; } else if (result is XAttribute) return ((XAttribute)result).Value; else if (result is XElement) return ((XElement)result).Value; return string.Empty; }
public static object Unwrap(XPathContext context, object expr) { if (expr is AtomizedUnaryOperatorNode || expr is AtomizedBinaryOperatorNode) { return(new UnwrapProxyNode(context, expr)); } return(expr); }
public override void LoadInnerXml(XmlNodeList nodeList) { // XPath transform is specified by text child of first XPath child if (nodeList == null) { throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform); } foreach (XmlNode node in nodeList) { string prefix = null; string namespaceURI = null; XmlElement elem = node as XmlElement; if (elem != null) { if (elem.LocalName == "XPath") { _xpathexpr = elem.InnerText.Trim(null); _context = new XPathContext(elem); XmlNodeReader nr = new XmlNodeReader(elem); XmlNameTable nt = nr.NameTable; _nsm = new XmlNamespaceManager(nt); if (!Utils.VerifyAttributes(elem, (string)null)) { throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform); } // Look for a namespace in the attributes foreach (XmlAttribute attrib in elem.Attributes) { if (attrib.Prefix == "xmlns") { prefix = attrib.LocalName; namespaceURI = attrib.Value; if (prefix == null) { prefix = elem.Prefix; namespaceURI = elem.NamespaceURI; } _nsm.AddNamespace(prefix, namespaceURI); } } break; } else { throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform); } } } if (_xpathexpr == null) { throw new CryptographicException(SR.Cryptography_Xml_UnknownTransform); } }
public void Attributes() { XPathContext ctx = new XPathContext(); ctx.SetChildren(Linqy.Singleton(new Element("foo"))); ctx.NavigateToChild(0); List<XmlQualifiedName> l = new List<XmlQualifiedName>(); l.Add(new XmlQualifiedName("bar")); ctx.AddAttributes(l); ctx.NavigateToAttribute(new XmlQualifiedName("bar")); Assert.AreEqual("/foo[1]/@bar", ctx.XPath); }
// TODO: Add variable support! public override object EvaluateFunction(XPathContext context, string name, object[] parameters) { if (name == "match-regex") { if (parameters.Length != 2) { throw new ArgumentException("Wrong number of parameters for the match-regex function."); } string str = ToString(parameters[0]), reg = ToString(parameters[1]); return(Regex.IsMatch(str, reg, RegexOptions.CultureInvariant)); } return(base.EvaluateFunction(context, name, parameters)); }
public void FiltersByScope(XmlNamespaceScope scope, int count) { // Default namespace and additional xml namespace var withXml = new XPathContext( new XPathContext().GetNamespacesInScope(XmlNamespaceScope.All), "xml", "http://www.w3.org/XML/1998/namespace"); // Default namespace and additional xml and smlns namespace var withXmlAndXmlns = new XPathContext( withXml.GetNamespacesInScope(XmlNamespaceScope.All), "xmlns", "http://www.w3.org/2000/xmlns/"); var y = withXmlAndXmlns.GetNamespacesInScope(scope); Assert.True( new LengthOf(withXmlAndXmlns.GetNamespacesInScope(scope)).Value() == count); }
public void AttributesAndNs() { Dictionary<string, string> m = new Dictionary<string, string>(); m["urn:foo:bar"] = "bar"; XPathContext ctx = new XPathContext(m); ctx.SetChildren(Linqy.Singleton(new Element("foo", "urn:foo:bar"))); ctx.NavigateToChild(0); List<XmlQualifiedName> l = new List<XmlQualifiedName>(); l.Add(new XmlQualifiedName("baz")); l.Add(new XmlQualifiedName("baz", "urn:foo:bar")); ctx.AddAttributes(l); ctx.NavigateToAttribute(new XmlQualifiedName("baz")); Assert.AreEqual("/bar:foo[1]/@baz", ctx.XPath); ctx.NavigateToParent(); ctx.NavigateToAttribute(new XmlQualifiedName("baz", "urn:foo:bar")); Assert.AreEqual("/bar:foo[1]/@bar:baz", ctx.XPath); ctx.NavigateToParent(); }
public void AppendChildren() { List<Element> l = new List<Element>(); l.Add(new Element("foo")); l.Add(new Element("foo")); XPathContext ctx = new XPathContext(); ctx.SetChildren(l); l = new List<Element>(); l.Add(new Element("bar")); l.Add(new Element("foo")); ctx.AppendChildren(l); ctx.NavigateToChild(0); Assert.AreEqual("/foo[1]", ctx.XPath); ctx.NavigateToParent(); ctx.NavigateToChild(1); Assert.AreEqual("/foo[2]", ctx.XPath); ctx.NavigateToParent(); ctx.NavigateToChild(2); Assert.AreEqual("/bar[1]", ctx.XPath); ctx.NavigateToParent(); ctx.NavigateToChild(3); Assert.AreEqual("/foo[3]", ctx.XPath); }
public void Mixed() { List<XPathContext.INodeInfo> l = new List<XPathContext.INodeInfo>(); l.Add(new Text()); l.Add(new Comment()); l.Add(new CDATA()); l.Add(new PI()); l.Add(new CDATA()); l.Add(new Comment()); l.Add(new PI()); l.Add(new Text()); XPathContext ctx = new XPathContext(); ctx.SetChildren(l); ctx.NavigateToChild(0); Assert.AreEqual("/text()[1]", ctx.XPath); ctx.NavigateToParent(); ctx.NavigateToChild(1); Assert.AreEqual("/comment()[1]", ctx.XPath); ctx.NavigateToParent(); ctx.NavigateToChild(2); Assert.AreEqual("/text()[2]", ctx.XPath); ctx.NavigateToParent(); ctx.NavigateToChild(3); Assert.AreEqual("/processing-instruction()[1]", ctx.XPath); ctx.NavigateToParent(); ctx.NavigateToChild(4); Assert.AreEqual("/text()[3]", ctx.XPath); ctx.NavigateToParent(); ctx.NavigateToChild(5); Assert.AreEqual("/comment()[2]", ctx.XPath); ctx.NavigateToParent(); ctx.NavigateToChild(6); Assert.AreEqual("/processing-instruction()[2]", ctx.XPath); ctx.NavigateToParent(); ctx.NavigateToChild(7); Assert.AreEqual("/text()[4]", ctx.XPath); }
/// <summary> /// Compares properties of the doctype declaration. /// </summary> private ComparisonResult CompareDocTypes(XmlDocumentType control, XPathContext controlContext, XmlDocumentType test, XPathContext testContext) { ComparisonResult lastResult = Compare(new Comparison(ComparisonType.DOCTYPE_NAME, control, GetXPath(controlContext), control.Name, test, GetXPath(testContext), test.Name)); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } lastResult = Compare(new Comparison(ComparisonType.DOCTYPE_PUBLIC_ID, control, GetXPath(controlContext), control.PublicId, test, GetXPath(testContext), test.PublicId)); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } return Compare(new Comparison(ComparisonType.DOCTYPE_SYSTEM_ID, control, GetXPath(controlContext), control.SystemId, test, GetXPath(testContext), test.SystemId)); }
/// <summary> /// Compares properties of XML declaration. /// </summary> private ComparisonResult CompareDeclarations(XmlDeclaration control, XPathContext controlContext, XmlDeclaration test, XPathContext testContext) { string controlVersion = control == null ? "1.0" : control.Version; string testVersion = test == null ? "1.0" : test.Version; ComparisonResult lastResult = Compare(new Comparison(ComparisonType.XML_VERSION, control, GetXPath(controlContext), controlVersion, test, GetXPath(testContext), testVersion)); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } string controlStandalone = control == null ? string.Empty : control.Standalone; string testStandalone = test == null ? string.Empty : test.Standalone; lastResult = Compare(new Comparison(ComparisonType.XML_STANDALONE, control, GetXPath(controlContext), controlStandalone, test, GetXPath(testContext), testStandalone)); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } string controlEncoding = control != null ? control.Encoding : string.Empty; string testEncoding = test != null ? test.Encoding : string.Empty; return Compare(new Comparison(ComparisonType.XML_ENCODING, control, GetXPath(controlContext), controlEncoding, test, GetXPath(testContext), testEncoding)); }
protected static string GetXPath(XPathContext ctx) { return ctx == null ? null : ctx.XPath; }
/// <summary> /// Compares document node, doctype and XML declaration properties /// </summary> private ComparisonResult CompareDocuments(XmlDocument control, XPathContext controlContext, XmlDocument test, XPathContext testContext) { XmlDocumentType controlDt = control.DocumentType; XmlDocumentType testDt = test.DocumentType; ComparisonResult lastResult = Compare(new Comparison(ComparisonType.HAS_DOCTYPE_DECLARATION, control, GetXPath(controlContext), controlDt != null, test, GetXPath(testContext), testDt != null)); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } if (controlDt != null && testDt != null) { lastResult = CompareNodes(controlDt, controlContext, testDt, testContext); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } } XmlDeclaration controlDecl = control.FirstChild as XmlDeclaration; XmlDeclaration testDecl = test.FirstChild as XmlDeclaration; return CompareDeclarations(controlDecl, controlContext, testDecl, testContext); }
/// <summary> /// Compares elements node properties, in particular the /// element's name and its attributes. /// </summary> private ComparisonResult CompareElements(XmlElement control, XPathContext controlContext, XmlElement test, XPathContext testContext) { ComparisonResult lastResult = Compare(new Comparison(ComparisonType.ELEMENT_TAG_NAME, control, GetXPath(controlContext), control.Name, test, GetXPath(testContext), test.Name)); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } Attributes controlAttributes = SplitAttributes(control.Attributes); controlContext .AddAttributes(Linqy.Map<XmlAttribute, XmlQualifiedName>(controlAttributes .RemainingAttributes, Nodes.GetQName)); Attributes testAttributes = SplitAttributes(test.Attributes); testContext .AddAttributes(Linqy.Map<XmlAttribute, XmlQualifiedName>(testAttributes .RemainingAttributes, Nodes.GetQName)); IDictionary<XmlAttribute, object> foundTestAttributes = new Dictionary<XmlAttribute, object>(); lastResult = Compare(new Comparison(ComparisonType.ELEMENT_NUM_ATTRIBUTES, control, GetXPath(controlContext), controlAttributes.RemainingAttributes.Count, test, GetXPath(testContext), testAttributes.RemainingAttributes.Count)); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } foreach (XmlAttribute controlAttr in controlAttributes.RemainingAttributes) { XmlAttribute testAttr = FindMatchingAttr(testAttributes.RemainingAttributes, controlAttr); controlContext.NavigateToAttribute(Nodes.GetQName(controlAttr)); try { lastResult = Compare(new Comparison(ComparisonType.ATTR_NAME_LOOKUP, control, GetXPath(controlContext), true, test, GetXPath(testContext), testAttr != null)); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } if (testAttr != null) { testContext.NavigateToAttribute(Nodes .GetQName(testAttr)); try { lastResult = CompareNodes(controlAttr, controlContext, testAttr, testContext); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } foundTestAttributes[testAttr] = DUMMY; } finally { testContext.NavigateToParent(); } } } finally { controlContext.NavigateToParent(); } } foreach (XmlAttribute testAttr in testAttributes.RemainingAttributes) { testContext.NavigateToAttribute(Nodes.GetQName(testAttr)); try { lastResult = Compare(new Comparison(ComparisonType.ATTR_NAME_LOOKUP, control, GetXPath(controlContext), foundTestAttributes.ContainsKey(testAttr), test, GetXPath(testContext), true)); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } } finally { testContext.NavigateToParent(); } } lastResult = Compare(new Comparison(ComparisonType.SCHEMA_LOCATION, control, GetXPath(controlContext), controlAttributes.SchemaLocation != null ? controlAttributes.SchemaLocation.Value : null, test, GetXPath(testContext), testAttributes.SchemaLocation != null ? testAttributes.SchemaLocation.Value : null)); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } return Compare(new Comparison(ComparisonType.NO_NAMESPACE_SCHEMA_LOCATION, control, GetXPath(controlContext), controlAttributes.NoNamespaceSchemaLocation != null ? controlAttributes.NoNamespaceSchemaLocation.Value : null, test, GetXPath(testContext), testAttributes.NoNamespaceSchemaLocation != null ? testAttributes.NoNamespaceSchemaLocation.Value : null)); }
public void ElementsAndNs() { List<Element> l = new List<Element>(); l.Add(new Element("foo", "urn:foo:foo")); l.Add(new Element("foo")); l.Add(new Element("foo", "urn:foo:bar")); Dictionary<string, string> m = new Dictionary<string, string>(); m["urn:foo:bar"] = "bar"; XPathContext ctx = new XPathContext(m); ctx.SetChildren(l); ctx.NavigateToChild(0); Assert.AreEqual("/foo[1]", ctx.XPath); ctx.NavigateToParent(); ctx.NavigateToChild(1); Assert.AreEqual("/foo[2]", ctx.XPath); ctx.NavigateToParent(); ctx.NavigateToChild(2); Assert.AreEqual("/bar:foo[1]", ctx.XPath); }
/// <summary> /// Matches nodes of two node lists and invokes compareNode on /// each pair. /// </summary> /// <remarks> /// Also performs CHILD_LOOKUP comparisons for each node that /// couldn't be matched to one of the "other" list. /// </remarks> private ComparisonResult CompareNodeLists(IEnumerable<XmlNode> controlSeq, XPathContext controlContext, IEnumerable<XmlNode> testSeq, XPathContext testContext) { // if there are no children on either Node, the result is equal ComparisonResult lastResult = ComparisonResult.EQUAL; IEnumerable<KeyValuePair<XmlNode, XmlNode>> matches = NodeMatcher.Match(controlSeq, testSeq); IList<XmlNode> controlList = new List<XmlNode>(controlSeq); IList<XmlNode> testList = new List<XmlNode>(testSeq); IDictionary<XmlNode, object> seen = new Dictionary<XmlNode, object>(); foreach (KeyValuePair<XmlNode, XmlNode> pair in matches) { XmlNode control = pair.Key; seen[control] = DUMMY; XmlNode test = pair.Value; seen[test] = DUMMY; int controlIndex = controlList.IndexOf(control); int testIndex = testList.IndexOf(test); controlContext.NavigateToChild(controlIndex); testContext.NavigateToChild(testIndex); try { lastResult = Compare(new Comparison(ComparisonType.CHILD_NODELIST_SEQUENCE, control, GetXPath(controlContext), controlIndex, test, GetXPath(testContext), testIndex)); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } lastResult = CompareNodes(control, controlContext, test, testContext); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } } finally { testContext.NavigateToParent(); controlContext.NavigateToParent(); } } int controlSize = controlList.Count; for (int i = 0; i < controlSize; i++) { if (!seen.ContainsKey(controlList[i])) { controlContext.NavigateToChild(i); try { lastResult = Compare(new Comparison(ComparisonType.CHILD_LOOKUP, controlList[i], GetXPath(controlContext), controlList[i], null, null, null)); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } } finally { controlContext.NavigateToParent(); } } } int testSize = testList.Count; for (int i = 0; i < testSize; i++) { if (!seen.ContainsKey(testList[i])) { testContext.NavigateToChild(i); try { lastResult = Compare(new Comparison(ComparisonType.CHILD_LOOKUP, null, null, null, testList[i], GetXPath(testContext), testList[i])); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } } finally { testContext.NavigateToParent(); } } } return lastResult; }
/// <summary> /// Compares textual content. /// </summary> private ComparisonResult CompareCharacterData(XmlCharacterData control, XPathContext controlContext, XmlCharacterData test, XPathContext testContext) { return Compare(new Comparison(ComparisonType.TEXT_VALUE, control, GetXPath(controlContext), control.Data, test, GetXPath(testContext), test.Data)); }
/// <summary> /// Compares properties of a processing instruction. /// </summary> private ComparisonResult CompareProcessingInstructions(XmlProcessingInstruction control, XPathContext controlContext, XmlProcessingInstruction test, XPathContext testContext) { ComparisonResult lastResult = Compare(new Comparison(ComparisonType.PROCESSING_INSTRUCTION_TARGET, control, GetXPath(controlContext), control.Target, test, GetXPath(testContext), test.Target)); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } return Compare(new Comparison(ComparisonType.PROCESSING_INSTRUCTION_DATA, control, GetXPath(controlContext), control.Data, test, GetXPath(testContext), test.Data)); }
/// <summary> /// Recursively compares two XML nodes. /// </summary> /// <remarks> /// Performs comparisons common to all node types, then performs /// the node type specific comparisons and finally recurses into /// the node's child lists. /// /// Stops as soon as any comparison returns ComparisonResult.CRITICAL. /// </remarks> internal ComparisonResult CompareNodes(XmlNode control, XPathContext controlContext, XmlNode test, XPathContext testContext) { ComparisonResult lastResult = Compare(new Comparison(ComparisonType.NODE_TYPE, control, GetXPath(controlContext), control.NodeType, test, GetXPath(testContext), test.NodeType)); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } lastResult = Compare(new Comparison(ComparisonType.NAMESPACE_URI, control, GetXPath(controlContext), control.NamespaceURI, test, GetXPath(testContext), test.NamespaceURI)); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } lastResult = Compare(new Comparison(ComparisonType.NAMESPACE_PREFIX, control, GetXPath(controlContext), control.Prefix, test, GetXPath(testContext), test.Prefix)); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } IEnumerable<XmlNode> controlChildren = Linqy.Filter(Linqy.Cast<XmlNode>(control.ChildNodes), INTERESTING_NODES); IEnumerable<XmlNode> testChildren = Linqy.Filter(Linqy.Cast<XmlNode>(test.ChildNodes), INTERESTING_NODES); if (control.NodeType != XmlNodeType.Attribute) { lastResult = Compare(new Comparison(ComparisonType.CHILD_NODELIST_LENGTH, control, GetXPath(controlContext), Linqy.Count(controlChildren), test, GetXPath(testContext), Linqy.Count(testChildren))); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } } lastResult = NodeTypeSpecificComparison(control, controlContext, test, testContext); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } if (control.NodeType != XmlNodeType.Attribute) { controlContext .SetChildren(Linqy.Map<XmlNode, XPathContext.INodeInfo>(controlChildren, TO_NODE_INFO)); testContext .SetChildren(Linqy.Map<XmlNode, XPathContext.INodeInfo>(testChildren, TO_NODE_INFO)); lastResult = CompareNodeLists(controlChildren, controlContext, testChildren, testContext); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } } return lastResult; }
/// <summary> /// Dispatches to the node type specific comparison if one is /// defined for the given combination of nodes. /// </summary> private ComparisonResult NodeTypeSpecificComparison(XmlNode control, XPathContext controlContext, XmlNode test, XPathContext testContext) { switch (control.NodeType) { case XmlNodeType.CDATA: case XmlNodeType.Comment: case XmlNodeType.Text: if (test is XmlCharacterData) { return CompareCharacterData((XmlCharacterData) control, controlContext, (XmlCharacterData) test, testContext); } break; case XmlNodeType.Document: if (test is XmlDocument) { return CompareDocuments((XmlDocument) control, controlContext, (XmlDocument) test, testContext); } break; case XmlNodeType.Element: if (test is XmlElement) { return CompareElements((XmlElement) control, controlContext, (XmlElement) test, testContext); } break; case XmlNodeType.ProcessingInstruction: if (test is XmlProcessingInstruction) { return CompareProcessingInstructions((XmlProcessingInstruction) control, controlContext, (XmlProcessingInstruction) test, testContext); } break; case XmlNodeType.DocumentType: if (test is XmlDocumentType) { return CompareDocTypes((XmlDocumentType) control, controlContext, (XmlDocumentType) test, testContext); } break; case XmlNodeType.Attribute: if (test is XmlAttribute) { return CompareAttributes((XmlAttribute) control, controlContext, (XmlAttribute) test, testContext); } break; } return ComparisonResult.EQUAL; }
public UnwrapProxyNode(XPathContext context, object node) : base(context) { Add(node); }
/// <summary> /// Compares properties of an attribute. /// </summary> private ComparisonResult CompareAttributes(XmlAttribute control, XPathContext controlContext, XmlAttribute test, XPathContext testContext) { ComparisonResult lastResult = Compare(new Comparison(ComparisonType.ATTR_VALUE_EXPLICITLY_SPECIFIED, control, GetXPath(controlContext), control.Specified, test, GetXPath(testContext), test.Specified)); if (lastResult == ComparisonResult.CRITICAL) { return lastResult; } return Compare(new Comparison(ComparisonType.ATTR_VALUE, control, GetXPath(controlContext), control.Value, test, GetXPath(testContext), test.Value)); }