From 9eb5c3578a32bbec1d9b2234faa22080e35a04d5 Mon Sep 17 00:00:00 2001 From: Davide Brunato Date: Sat, 30 Jan 2021 09:13:53 +0100 Subject: [PATCH] Add tests for fn:id()/fn:element-with-id() with schemas --- elementpath/xpath2/xpath2_functions.py | 8 +- tests/test_xpath2_functions.py | 101 +++++++++++++++++++++++-- 2 files changed, 98 insertions(+), 11 deletions(-) diff --git a/elementpath/xpath2/xpath2_functions.py b/elementpath/xpath2/xpath2_functions.py index 1028b81a..8e4a27c9 100644 --- a/elementpath/xpath2/xpath2_functions.py +++ b/elementpath/xpath2/xpath2_functions.py @@ -1232,10 +1232,6 @@ def select(self, context=None): node = self.get_argument(context, index=1, default_to_context=True) if isinstance(context, XPathSchemaContext): return - elif context is None or node is not context.item: - pass - elif context.item is None: - node = context.root if not is_xpath_node(node): raise self.error('XPTY0004') @@ -1258,7 +1254,7 @@ def select(self, context=None): parent = context.get_parent(elem) if parent is not None: yield parent - continue + continue # pragma: no cover for attr in map(lambda x: AttributeNode(*x), elem.attrib.items()): if attr.value in idrefs: @@ -1270,7 +1266,7 @@ def select(self, context=None): xsd_attribute = xsd_element.attrib.get(attr.name) if xsd_attribute is None or not xsd_attribute.type.is_key(): - continue + continue # pragma: no cover idrefs.remove(attr.value) yield elem diff --git a/tests/test_xpath2_functions.py b/tests/test_xpath2_functions.py index 6ffd688e..e2b5a652 100644 --- a/tests/test_xpath2_functions.py +++ b/tests/test_xpath2_functions.py @@ -1100,9 +1100,7 @@ def test_node_set_id_function(self): self.check_selector('element-with-id("foo")', root, [root[0]]) self.check_selector('id("foo")', root, [root[0]]) - doc = self.etree.parse( - io.StringIO('') - ) + doc = self.etree.ElementTree(root) root = doc.getroot() self.check_selector('id("foo")', doc, [root[0]]) self.check_selector('id("fox")', doc, []) @@ -1122,6 +1120,9 @@ def test_node_set_id_function(self): self.check_selector("id('ID21256')", doc, [root]) self.check_selector("id('E21256')", doc, [root[0]]) + self.check_selector('element-with-id("ID21256")', doc, [root]) + self.check_selector('element-with-id("E21256")', doc, [root]) + with self.assertRaises(MissingContextError) as err: self.check_value("id('ID21256')") self.assertIn('XPDY0002', str(err.exception)) @@ -1139,6 +1140,96 @@ def test_node_set_id_function(self): context = XPathContext(doc, item=root, variables={'x': root}) self.check_value("id('ID21256', $x)", [root], context=context) + # Id on root element + root = self.etree.XML("E21256") + self.check_selector("id('E21256')", root, [root]) + self.check_selector('element-with-id("E21256")', root, []) + + @unittest.skipIf(xmlschema is None, "xmlschema library is not installed ...") + def test_node_set_id_function_with_schema(self): + root = self.etree.XML(dedent("""\ + + E21256 + John + Brown + """)) + doc = self.etree.ElementTree(root) + + # Test with matching value of type xs:ID + schema = xmlschema.XMLSchema(dedent("""\ + + + + + + + + + + + + + """)) + + self.assertTrue(schema.is_valid(root)) + with self.schema_bound_parser(schema.xpath_proxy): + context = XPathContext(doc) + self.check_select("id('ID21256')", [root], context) + self.check_select("id('E21256')", [root[0]], context) + + # Test with matching value of type xs:string + schema = xmlschema.XMLSchema(dedent("""\ + + + + + + + + + + + + + """)) + + self.assertTrue(schema.is_valid(root)) + with self.schema_bound_parser(schema.xpath_proxy): + context = XPathContext(doc) + self.check_select("id('E21256')", [], context) + + @unittest.skipIf(xmlschema is None, "xmlschema library is not installed ...") + def test_node_set_id_function_with_wrong_schema(self): + root = self.etree.XML(dedent("""\ + + E21256 + John + Brown + """)) + doc = self.etree.ElementTree(root) + + schema = xmlschema.XMLSchema(dedent("""\ + + + """)) + + self.assertFalse(schema.is_valid(root)) + with self.schema_bound_parser(schema.xpath_proxy): + context = XPathContext(doc) + self.check_select("id('ID21256')", [], context) + self.check_select("id('E21256')", [], context) + + schema = xmlschema.XMLSchema(dedent("""\ + + + """)) + + self.assertFalse(schema.is_valid(root)) + with self.schema_bound_parser(schema.xpath_proxy): + context = XPathContext(doc) + self.check_select("id('ID21256')", [], context) + self.check_select("id('E21256')", [], context) + def test_node_set_idref_function(self): doc = self.etree.parse(io.StringIO(""" @@ -1497,11 +1588,11 @@ def test_root_function(self): self.check_value("root($elem)", doc2, context=context) if xmlschema is not None: - schema = xmlschema.XMLSchema(""" + schema = xmlschema.XMLSchema(dedent("""\ - """) + """)) with self.schema_bound_parser(schema.xpath_proxy): context = self.parser.schema.get_context()