Exemple #1
0
 def test_get_attribute_method(self):
     schema_proxy = XMLSchemaProxy(self.xs1)
     qname = '{%s}step' % self.xs1.target_namespace
     self.assertIs(schema_proxy.get_attribute(qname),
                   self.xs1.attributes['step'])
     qname = '{%s}unknown' % self.xs1.target_namespace
     self.assertIsNone(schema_proxy.get_attribute(qname))
Exemple #2
0
 def test_iter_atomic_types_method(self):
     schema_proxy = XMLSchemaProxy(self.xs3)
     k = 0
     for k, xsd_type in enumerate(schema_proxy.iter_atomic_types(), start=1):
         self.assertNotIn(XSD_NAMESPACE, xsd_type.name)
         self.assertIsInstance(xsd_type, (XsdAtomic, XsdAtomicRestriction))
     self.assertGreater(k, 10)
Exemple #3
0
 def test_get_element_method(self):
     schema_proxy = XMLSchemaProxy(self.xs1)
     qname = '{%s}cars' % self.xs1.target_namespace
     self.assertIs(schema_proxy.get_element(qname),
                   self.xs1.elements['cars'])
     qname = '{%s}unknown' % self.xs1.target_namespace
     self.assertIsNone(schema_proxy.get_element(qname))
Exemple #4
0
 def test_get_type_method(self):
     schema_proxy = XMLSchemaProxy(self.xs1)
     qname = '{%s}vehicleType' % self.xs1.target_namespace
     self.assertIs(schema_proxy.get_type(qname),
                   self.xs1.types['vehicleType'])
     qname = '{%s}unknown' % self.xs1.target_namespace
     self.assertIsNone(schema_proxy.get_type(qname))
 def test_find_api(self):
     schema_src = """<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
                         <xs:element name="test_element" type="xs:string"/>
                     </xs:schema>"""
     schema = xmlschema.XMLSchema(schema_src)
     schema_proxy = XMLSchemaProxy(schema=schema)
     self.assertEqual(schema_proxy.find('/test_element'),
                      schema.elements['test_element'])
Exemple #6
0
 def test_get_substitution_group_method(self):
     schema = XMLSchema11.meta_schema
     schema.build()
     schema_proxy = XMLSchemaProxy(schema)
     qname = '{%s}facet' % schema.target_namespace
     self.assertIs(schema_proxy.get_substitution_group(qname),
                   schema.substitution_groups['facet'])
     qname = '{%s}unknown' % schema.target_namespace
     self.assertIsNone(schema_proxy.get_substitution_group(qname))
Exemple #7
0
    def test_get_primitive_type_method(self):
        schema_proxy = XMLSchemaProxy(self.xs3)

        string_type = self.xs3.meta_schema.types['string']
        xsd_type = self.xs3.types['list_of_strings']
        self.assertIs(schema_proxy.get_primitive_type(xsd_type), string_type)

        xsd_type = self.xs3.types['integer_or_float']
        self.assertIs(schema_proxy.get_primitive_type(xsd_type), xsd_type)
 def test_find_api(self):
     schema_src = """<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
                         <xs:element name="test_element" type="xs:string"/>
                     </xs:schema>"""
     schema = xmlschema.XMLSchema(schema_src)
     schema_proxy = XMLSchemaProxy(schema=schema)
     if xmlschema.__version__ == '1.0.14':
         self.assertIsNone(
             schema_proxy.find('/test_element'))  # Not implemented!
     else:
         self.assertEqual(schema_proxy.find('/test_element'),
                          schema.elements['test_element'])
    def test_attributes_type(self):
        parser = XPath2Parser(namespaces=self.namespaces)
        token = parser.parse("@min le @max")
        self.assertTrue(
            token.evaluate(context=XPathContext(
                self.etree.XML('<root min="10" max="20" />'))))
        self.assertTrue(
            token.evaluate(context=XPathContext(
                self.etree.XML('<root min="10" max="2" />'))))

        schema = xmlschema.XMLSchema('''
            <xs:schema xmlns="http://xpath.test/ns" xmlns:xs="http://www.w3.org/2001/XMLSchema"
                targetNamespace="http://xpath.test/ns">
              <xs:element name="range" type="intRange"/>
              <xs:complexType name="intRange">
                <xs:attribute name="min" type="xs:int"/>
                <xs:attribute name="max" type="xs:int"/>
              </xs:complexType>
            </xs:schema>''')
        parser = XPath2Parser(namespaces=self.namespaces,
                              schema=XMLSchemaProxy(schema,
                                                    schema.elements['range']))
        token = parser.parse("@min le @max")
        self.assertTrue(
            token.evaluate(context=XPathContext(
                self.etree.XML('<root min="10" max="20" />'))))
        self.assertFalse(
            token.evaluate(context=XPathContext(
                self.etree.XML('<root min="10" max="2" />'))))

        schema = xmlschema.XMLSchema('''
            <xs:schema xmlns="http://xpath.test/ns" xmlns:xs="http://www.w3.org/2001/XMLSchema"
                targetNamespace="http://xpath.test/ns">
              <xs:element name="range" type="intRange"/>
              <xs:complexType name="intRange">
                <xs:attribute name="min" type="xs:int"/>
                <xs:attribute name="max" type="xs:string"/>
              </xs:complexType>
            </xs:schema>''')
        parser = XPath2Parser(namespaces=self.namespaces,
                              schema=XMLSchemaProxy(schema,
                                                    schema.elements['range']))
        if PY3:
            self.assertRaises(TypeError, parser.parse, '@min le @max')
        else:
            # In Python 2 strings and numbers are comparable and strings are 'greater than' numbers.
            token = parser.parse("@min le @max")
            self.assertTrue(
                token.evaluate(context=XPathContext(
                    self.etree.XML('<root min="10" max="20" />'))))
            self.assertTrue(
                token.evaluate(context=XPathContext(
                    self.etree.XML('<root min="10" max="2" />'))))
Exemple #10
0
    def test_initialization(self):
        schema_proxy = XMLSchemaProxy()
        self.assertIs(schema_proxy._schema, self.schema_class.meta_schema)

        schema_proxy = XMLSchemaProxy(self.xs1, base_element=self.xs1.elements['vehicles'])
        self.assertIs(schema_proxy._schema, self.xs1)

        with self.assertRaises(ValueError):
            XMLSchemaProxy(self.xs1, base_element=self.xs2.elements['collection'])

        with self.assertRaises(TypeError):
            XMLSchemaProxy(self.xs1, base_element=ElementTree.Element('vehicles'))
Exemple #11
0
 def test_bind_parser_method(self):
     schema_proxy1 = XMLSchemaProxy(self.xs1)
     schema_proxy2 = XMLSchemaProxy(self.xs2)
     parser = XPath2Parser(strict=False, schema=schema_proxy1)
     self.assertIs(parser.schema, schema_proxy1)
     schema_proxy1.bind_parser(parser)
     self.assertIs(parser.schema, schema_proxy1)
     schema_proxy2.bind_parser(parser)
     self.assertIs(parser.schema, schema_proxy2)
    def test_bind_parser_method(self):
        schema_src = """<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
                            <xs:simpleType name="test_type">
                              <xs:restriction base="xs:string"/>
                            </xs:simpleType>
                        </xs:schema>"""
        schema = xmlschema.XMLSchema(schema_src)

        schema_proxy = XMLSchemaProxy(schema=schema)
        parser = XPath2Parser(namespaces=self.namespaces)
        schema_proxy.bind_parser(parser)
        self.assertIs(schema_proxy, parser.schema)
        parser = XPath2Parser(namespaces=self.namespaces)
        super(XMLSchemaProxy, schema_proxy).bind_parser(parser)
        self.assertIs(schema_proxy, parser.schema)
        super(XMLSchemaProxy, schema_proxy).bind_parser(parser)
        self.assertIs(schema_proxy, parser.schema)
    def test_bind_parser_method(self):
        schema_src = dedent("""
            <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
                <xs:simpleType name="stringType">
                    <xs:restriction base="xs:string"/>
                </xs:simpleType>
            </xs:schema>""")
        schema = xmlschema.XMLSchema(schema_src)

        schema_proxy = XMLSchemaProxy(schema=schema)
        parser = XPath2Parser(namespaces=self.namespaces)
        self.assertFalse(parser.is_schema_bound())

        schema_proxy.bind_parser(parser)
        self.assertTrue(parser.is_schema_bound())
        self.assertIs(schema_proxy, parser.schema)

        # To test AbstractSchemaProxy.bind_parser()
        parser = XPath2Parser(namespaces=self.namespaces)
        super(XMLSchemaProxy, schema_proxy).bind_parser(parser)
        self.assertIs(schema_proxy, parser.schema)
        super(XMLSchemaProxy, schema_proxy).bind_parser(parser)
        self.assertIs(schema_proxy, parser.schema)
    def test_schema_constructors(self):
        schema_src = dedent("""
            <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
                <xs:simpleType name="stringType">
                    <xs:restriction base="xs:string"/>
                </xs:simpleType>
                <xs:simpleType name="intType">
                    <xs:restriction base="xs:int"/>
                </xs:simpleType>
            </xs:schema>""")
        schema = xmlschema.XMLSchema(schema_src)
        schema_proxy = XMLSchemaProxy(schema=schema)
        parser = XPath2Parser(namespaces=self.namespaces, schema=schema_proxy)

        with self.assertRaises(NameError) as ctx:
            parser.schema_constructor(XSD_ANY_ATOMIC_TYPE)
        self.assertIn('XPST0080', str(ctx.exception))

        with self.assertRaises(NameError) as ctx:
            parser.schema_constructor(XSD_NOTATION)
        self.assertIn('XPST0080', str(ctx.exception))

        token = parser.parse('stringType("apple")')
        self.assertEqual(token.symbol, 'stringType')
        self.assertEqual(token.label, 'constructor function')
        self.assertEqual(token.evaluate(), 'apple')

        token = parser.parse('stringType(())')
        self.assertEqual(token.symbol, 'stringType')
        self.assertEqual(token.label, 'constructor function')
        self.assertEqual(token.evaluate(), [])

        token = parser.parse('stringType(10)')
        self.assertEqual(token.symbol, 'stringType')
        self.assertEqual(token.label, 'constructor function')
        self.assertEqual(token.evaluate(), '10')

        token = parser.parse('stringType(.)')
        self.assertEqual(token.symbol, 'stringType')
        self.assertEqual(token.label, 'constructor function')

        token = parser.parse('intType(10)')
        self.assertEqual(token.symbol, 'intType')
        self.assertEqual(token.label, 'constructor function')
        self.assertEqual(token.evaluate(), 10)

        with self.assertRaises(ValueError) as ctx:
            parser.parse('intType(true())')
        self.assertIn('FORG0001', str(ctx.exception))
    def test_elements_type(self):
        schema = xmlschema.XMLSchema('''
            <xs:schema xmlns="http://xpath.test/ns" xmlns:xs="http://www.w3.org/2001/XMLSchema"
                    targetNamespace="http://xpath.test/ns">
                <xs:element name="values">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="a" type="xs:string"/>
                            <xs:element name="b" type="xs:integer"/>
                            <xs:element name="c" type="xs:boolean"/>
                            <xs:element name="d" type="xs:float"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:schema>''')
        parser = XPath2Parser(namespaces={
            '': "http://xpath.test/ns",
            'xs': XSD_NAMESPACE
        },
                              schema=XMLSchemaProxy(schema))

        token = parser.parse("//a")
        self.assertEqual(token[0].xsd_types['a'],
                         schema.maps.types['{%s}string' % XSD_NAMESPACE])
        token = parser.parse("//b")
        self.assertEqual(token[0].xsd_types['b'],
                         schema.maps.types['{%s}integer' % XSD_NAMESPACE])
        token = parser.parse("//values/c")

        self.assertEqual(token[0][0].xsd_types["{http://xpath.test/ns}values"],
                         schema.elements['values'].type)
        self.assertEqual(token[1].xsd_types['c'],
                         schema.maps.types['{%s}boolean' % XSD_NAMESPACE])

        token = parser.parse("values/c")
        self.assertEqual(token[0].xsd_types['{http://xpath.test/ns}values'],
                         schema.elements['values'].type)
        self.assertEqual(token[1].xsd_types['c'],
                         schema.maps.types['{%s}boolean' % XSD_NAMESPACE])

        token = parser.parse("values/*")
        self.assertEqual(
            token[1].xsd_types, {
                'a': schema.maps.types['{%s}string' % XSD_NAMESPACE],
                'b': schema.maps.types['{%s}integer' % XSD_NAMESPACE],
                'c': schema.maps.types['{%s}boolean' % XSD_NAMESPACE],
                'd': schema.maps.types['{%s}float' % XSD_NAMESPACE],
            })
    def test_schema_proxy_init(self):
        schema_src = """<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
                            <xs:element name="test_element" type="xs:string"/>
                        </xs:schema>"""
        schema_tree = ElementTree.parse(io.StringIO(schema_src))

        self.assertIsInstance(XMLSchemaProxy(), XMLSchemaProxy)
        self.assertIsInstance(XMLSchemaProxy(xmlschema.XMLSchema(schema_src)),
                              XMLSchemaProxy)
        with self.assertRaises(TypeError):
            XMLSchemaProxy(schema=schema_tree)
        with self.assertRaises(TypeError):
            XMLSchemaProxy(schema=xmlschema.XMLSchema(schema_src),
                           base_element=schema_tree)
        with self.assertRaises(TypeError):
            XMLSchemaProxy(schema=xmlschema.XMLSchema(schema_src),
                           base_element=schema_tree.getroot())

        schema = xmlschema.XMLSchema(schema_src)
        with self.assertRaises(ValueError):
            XMLSchemaProxy(base_element=schema.elements['test_element'])
 def setUp(self):
     self.schema_proxy = XMLSchemaProxy(self.schema)
     self.parser = XPath2Parser(namespaces=self.namespaces,
                                schema=self.schema_proxy,
                                variables=self.variables)
class XPath2ParserXMLSchemaTest(test_xpath2_parser.XPath2ParserTest):
    @classmethod
    def setUpClass(cls):
        cls.schema = xmlschema.XMLSchema('''
        <!-- Dummy schema for testing proxy API -->
        <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://xpath.test/ns">
          <xs:element name="test_element" type="xs:string"/>
          <xs:attribute name="test_attribute" type="xs:string"/>
        </xs:schema>''')

    def setUp(self):
        self.schema_proxy = XMLSchemaProxy(self.schema)
        self.parser = XPath2Parser(namespaces=self.namespaces,
                                   schema=self.schema_proxy,
                                   variables=self.variables)

    def test_schema_proxy_init(self):
        schema_src = """<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
                            <xs:element name="test_element" type="xs:string"/>
                        </xs:schema>"""
        schema_tree = ElementTree.parse(io.StringIO(schema_src))

        self.assertIsInstance(XMLSchemaProxy(), XMLSchemaProxy)
        self.assertIsInstance(XMLSchemaProxy(xmlschema.XMLSchema(schema_src)),
                              XMLSchemaProxy)
        with self.assertRaises(TypeError):
            XMLSchemaProxy(schema=schema_tree)
        with self.assertRaises(TypeError):
            XMLSchemaProxy(schema=xmlschema.XMLSchema(schema_src),
                           base_element=schema_tree)
        with self.assertRaises(TypeError):
            XMLSchemaProxy(schema=xmlschema.XMLSchema(schema_src),
                           base_element=schema_tree.getroot())

        schema = xmlschema.XMLSchema(schema_src)
        with self.assertRaises(ValueError):
            XMLSchemaProxy(base_element=schema.elements['test_element'])

    def test_xmlschema_proxy(self):
        context = XPathContext(root=self.etree.XML(
            '<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"/>'))

        self.wrong_name("schema-element(nil)")
        self.wrong_name("schema-element(xs:string)")
        self.check_value("schema-element(xs:complexType)", None)
        self.check_value("schema-element(xs:schema)", context.item, context)
        self.check_tree("schema-element(xs:group)",
                        '(schema-element (: (xs) (group)))')

        context.item = AttributeNode(XML_LANG, 'en')
        self.wrong_name("schema-attribute(nil)")
        self.wrong_name("schema-attribute(xs:string)")
        self.check_value("schema-attribute(xml:lang)", None)
        self.check_value("schema-attribute(xml:lang)", context.item, context)
        self.check_tree("schema-attribute(xsi:schemaLocation)",
                        '(schema-attribute (: (xsi) (schemaLocation)))')

    def test_bind_parser_method(self):
        schema_src = """<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
                            <xs:simpleType name="test_type">
                              <xs:restriction base="xs:string"/>
                            </xs:simpleType>
                        </xs:schema>"""
        schema = xmlschema.XMLSchema(schema_src)

        schema_proxy = XMLSchemaProxy(schema=schema)
        parser = XPath2Parser(namespaces=self.namespaces)
        schema_proxy.bind_parser(parser)
        self.assertIs(schema_proxy, parser.schema)
        parser = XPath2Parser(namespaces=self.namespaces)
        super(XMLSchemaProxy, schema_proxy).bind_parser(parser)
        self.assertIs(schema_proxy, parser.schema)
        super(XMLSchemaProxy, schema_proxy).bind_parser(parser)
        self.assertIs(schema_proxy, parser.schema)

    def test_get_context_method(self):
        schema_proxy = XMLSchemaProxy()
        self.assertIsInstance(schema_proxy.get_context(), XPathContext)
        self.assertIsInstance(
            super(XMLSchemaProxy, schema_proxy).get_context(), XPathContext)

    def test_get_type_api(self):
        schema_proxy = XMLSchemaProxy()
        self.assertIsNone(schema_proxy.get_type('unknown'))
        self.assertEqual(schema_proxy.get_type('{%s}string' % XSD_NAMESPACE),
                         xmlschema.XMLSchema.builtin_types()['string'])

    def test_get_primitive_type_api(self):
        schema_proxy = XMLSchemaProxy()
        short_type = schema_proxy.get_type('{%s}short' % XSD_NAMESPACE)
        decimal_type = schema_proxy.get_type('{%s}decimal' % XSD_NAMESPACE)
        self.assertEqual(schema_proxy.get_primitive_type(short_type),
                         decimal_type)

        ntokens_type = schema_proxy.get_type('{%s}NMTOKENS' % XSD_NAMESPACE)
        string_type = schema_proxy.get_type('{%s}string' % XSD_NAMESPACE)
        self.assertEqual(schema_proxy.get_primitive_type(ntokens_type),
                         string_type)

        facet_type = schema_proxy.get_type('{%s}facet' % XSD_NAMESPACE)
        any_type = schema_proxy.get_type('{%s}anyType' % XSD_NAMESPACE)
        self.assertEqual(schema_proxy.get_primitive_type(facet_type), any_type)
        self.assertEqual(schema_proxy.get_primitive_type(any_type), any_type)

        any_simple_type = schema_proxy.get_type('{%s}anySimpleType' %
                                                XSD_NAMESPACE)
        self.assertEqual(schema_proxy.get_primitive_type(any_simple_type),
                         any_simple_type)

    def test_find_api(self):
        schema_src = """<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
                            <xs:element name="test_element" type="xs:string"/>
                        </xs:schema>"""
        schema = xmlschema.XMLSchema(schema_src)
        schema_proxy = XMLSchemaProxy(schema=schema)
        if xmlschema.__version__ == '1.0.14':
            self.assertIsNone(
                schema_proxy.find('/test_element'))  # Not implemented!
        else:
            self.assertEqual(schema_proxy.find('/test_element'),
                             schema.elements['test_element'])

    def test_is_instance_api(self):
        self.assertFalse(
            self.schema_proxy.is_instance(True, '{%s}integer' % XSD_NAMESPACE))
        self.assertTrue(
            self.schema_proxy.is_instance(5, '{%s}integer' % XSD_NAMESPACE))
        self.assertFalse(
            self.schema_proxy.is_instance('alpha',
                                          '{%s}integer' % XSD_NAMESPACE))
        self.assertTrue(
            self.schema_proxy.is_instance('alpha',
                                          '{%s}string' % XSD_NAMESPACE))
        self.assertTrue(
            self.schema_proxy.is_instance('alpha beta',
                                          '{%s}token' % XSD_NAMESPACE))
        self.assertTrue(
            self.schema_proxy.is_instance('alpha', '{%s}Name' % XSD_NAMESPACE))
        self.assertFalse(
            self.schema_proxy.is_instance('alpha beta',
                                          '{%s}Name' % XSD_NAMESPACE))
        self.assertFalse(
            self.schema_proxy.is_instance('1alpha',
                                          '{%s}Name' % XSD_NAMESPACE))
        self.assertTrue(
            self.schema_proxy.is_instance('alpha',
                                          '{%s}NCName' % XSD_NAMESPACE))
        self.assertFalse(
            self.schema_proxy.is_instance('eg:alpha',
                                          '{%s}NCName' % XSD_NAMESPACE))

    def test_cast_as_api(self):
        schema_proxy = XMLSchemaProxy()
        self.assertEqual(
            schema_proxy.cast_as('19', '{%s}short' % XSD_NAMESPACE), 19)

    def test_attributes_type(self):
        parser = XPath2Parser(namespaces=self.namespaces)
        token = parser.parse("@min le @max")
        self.assertTrue(
            token.evaluate(context=XPathContext(
                self.etree.XML('<root min="10" max="20" />'))))
        self.assertTrue(
            token.evaluate(context=XPathContext(
                self.etree.XML('<root min="10" max="2" />'))))

        schema = xmlschema.XMLSchema('''
            <xs:schema xmlns="http://xpath.test/ns" xmlns:xs="http://www.w3.org/2001/XMLSchema"
                targetNamespace="http://xpath.test/ns">
              <xs:element name="range" type="intRange"/>
              <xs:complexType name="intRange">
                <xs:attribute name="min" type="xs:int"/>
                <xs:attribute name="max" type="xs:int"/>
              </xs:complexType>
            </xs:schema>''')
        parser = XPath2Parser(namespaces=self.namespaces,
                              schema=XMLSchemaProxy(schema,
                                                    schema.elements['range']))
        token = parser.parse("@min le @max")
        self.assertTrue(
            token.evaluate(context=XPathContext(
                self.etree.XML('<root min="10" max="20" />'))))
        self.assertFalse(
            token.evaluate(context=XPathContext(
                self.etree.XML('<root min="10" max="2" />'))))

        schema = xmlschema.XMLSchema('''
            <xs:schema xmlns="http://xpath.test/ns" xmlns:xs="http://www.w3.org/2001/XMLSchema"
                targetNamespace="http://xpath.test/ns">
              <xs:element name="range" type="intRange"/>
              <xs:complexType name="intRange">
                <xs:attribute name="min" type="xs:int"/>
                <xs:attribute name="max" type="xs:string"/>
              </xs:complexType>
            </xs:schema>''')
        parser = XPath2Parser(namespaces=self.namespaces,
                              schema=XMLSchemaProxy(schema,
                                                    schema.elements['range']))
        if PY3:
            self.assertRaises(TypeError, parser.parse, '@min le @max')
        else:
            # In Python 2 strings and numbers are comparable and strings are 'greater than' numbers.
            token = parser.parse("@min le @max")
            self.assertTrue(
                token.evaluate(context=XPathContext(
                    self.etree.XML('<root min="10" max="20" />'))))
            self.assertTrue(
                token.evaluate(context=XPathContext(
                    self.etree.XML('<root min="10" max="2" />'))))

    def test_elements_type(self):
        schema = xmlschema.XMLSchema('''
            <xs:schema xmlns="http://xpath.test/ns" xmlns:xs="http://www.w3.org/2001/XMLSchema"
                    targetNamespace="http://xpath.test/ns">
                <xs:element name="values">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="a" type="xs:string"/>
                            <xs:element name="b" type="xs:integer"/>
                            <xs:element name="c" type="xs:boolean"/>
                            <xs:element name="d" type="xs:float"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:schema>''')
        parser = XPath2Parser(namespaces={
            '': "http://xpath.test/ns",
            'xs': XSD_NAMESPACE
        },
                              schema=XMLSchemaProxy(schema))
        token = parser.parse("//a")
        self.assertEqual(token[0].xsd_type,
                         schema.maps.types['{%s}string' % XSD_NAMESPACE])
        token = parser.parse("//b")
        self.assertEqual(token[0].xsd_type,
                         schema.maps.types['{%s}integer' % XSD_NAMESPACE])
        token = parser.parse("//values/c")
        self.assertEqual(token[0][0].xsd_type, schema.elements['values'].type)
        self.assertEqual(token[1].xsd_type,
                         schema.maps.types['{%s}boolean' % XSD_NAMESPACE])
        token = parser.parse("values/c")
        self.assertEqual(token[0].xsd_type, schema.elements['values'].type)
        self.assertEqual(token[1].xsd_type,
                         schema.maps.types['{%s}boolean' % XSD_NAMESPACE])

        schema = xmlschema.XMLSchema('''
            <xs:schema xmlns="http://xpath.test/ns" xmlns:xs="http://www.w3.org/2001/XMLSchema"
                    targetNamespace="http://xpath.test/ns">
                <xs:element name="values">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="a" type="xs:string"/>
                            <xs:element name="b" type="rangeType"/>
                            <xs:element name="c" type="xs:boolean"/>
                            <xs:element name="d" type="xs:float"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:complexType name="rangeType">
                    <xs:simpleContent>
                        <xs:extension base="xs:integer">
                            <xs:attribute name="min" type="xs:integer"/>
                            <xs:attribute name="max" type="xs:integer"/>
                        </xs:extension>
                    </xs:simpleContent>
                </xs:complexType>
            </xs:schema>''')
        parser = XPath2Parser(namespaces={
            '': "http://xpath.test/ns",
            'xs': XSD_NAMESPACE
        },
                              schema=XMLSchemaProxy(schema))
        token = parser.parse("//a")
        self.assertEqual(token[0].xsd_type,
                         schema.maps.types['{%s}string' % XSD_NAMESPACE])
        token = parser.parse("//b")
        self.assertEqual(token[0].xsd_type, schema.types['rangeType'])
        token = parser.parse("values/c")
        self.assertEqual(token[0].xsd_type, schema.elements['values'].type)
        self.assertEqual(token[1].xsd_type,
                         schema.maps.types['{%s}boolean' % XSD_NAMESPACE])
        token = parser.parse("//b/@min")
        self.assertEqual(token[0][0].xsd_type, schema.types['rangeType'])
        self.assertEqual(token[1][0].xsd_type,
                         schema.maps.types['{%s}integer' % XSD_NAMESPACE])
        token = parser.parse("values/b/@min")
        self.assertEqual(token[0][0].xsd_type, schema.elements['values'].type)
        self.assertEqual(token[0][1].xsd_type, schema.types['rangeType'])
        self.assertEqual(token[1][0].xsd_type,
                         schema.maps.types['{%s}integer' % XSD_NAMESPACE])

        token = parser.parse("//b/@min lt //b/@max")
        self.assertEqual(token[0][0][0].xsd_type, schema.types['rangeType'])
        self.assertEqual(token[0][1][0].xsd_type,
                         schema.maps.types['{%s}integer' % XSD_NAMESPACE])
        self.assertEqual(token[1][0][0].xsd_type, schema.types['rangeType'])
        self.assertEqual(token[1][1][0].xsd_type,
                         schema.maps.types['{%s}integer' % XSD_NAMESPACE])

        root = self.etree.XML(
            '<values xmlns="http://xpath.test/ns"><b min="19"/></values>')
        with self.assertRaises(TypeError):
            token.evaluate(context=XPathContext(root))

        root = self.etree.XML(
            '<values xmlns="http://xpath.test/ns"><b min="19">30</b></values>')
        self.assertIsNone(token.evaluate(context=XPathContext(root)))

        root = self.etree.XML(
            '<values xmlns="http://xpath.test/ns"><b min="19" max="40">30</b></values>'
        )
        context = XPathContext(root)
        self.assertTrue(token.evaluate(context))

        root = self.etree.XML(
            '<values xmlns="http://xpath.test/ns"><b min="19" max="10">30</b></values>'
        )
        context = XPathContext(root)
        self.assertFalse(token.evaluate(context))

    def test_instance_of_expression(self):
        element = self.etree.Element('schema')
        context = XPathContext(element)

        # Test cases from https://www.w3.org/TR/xpath20/#id-instance-of
        self.check_value("5 instance of xs:integer", True)
        self.check_value("5 instance of xs:decimal", True)
        self.check_value(
            "9.0 instance of xs:integer", False if
            [int(n)
             for n in xmlschema.__version__.split('.')] >= [1, 0, 8] else True)
        self.check_value("(5, 6) instance of xs:integer+", True)
        self.check_value(". instance of element()", True, context)

        self.check_value("(5, 6) instance of xs:integer", False)
        self.check_value("(5, 6) instance of xs:integer*", True)
        self.check_value("(5, 6) instance of xs:integer?", False)

        self.check_value("5 instance of empty-sequence()", False)
        self.check_value("() instance of empty-sequence()", True)

    def test_treat_as_expression(self):
        element = self.etree.Element('schema')
        context = XPathContext(element)

        self.check_value("5 treat as xs:integer", [5])
        # self.check_value("5 treat as xs:string", ElementPathTypeError)   # FIXME: a bug of xmlschema!
        self.check_value("5 treat as xs:decimal", [5])
        self.check_value("(5, 6) treat as xs:integer+", [5, 6])
        self.check_value(". treat as element()", [element], context)

        self.check_value("(5, 6) treat as xs:integer", ElementPathTypeError)
        self.check_value("(5, 6) treat as xs:integer*", [5, 6])
        self.check_value("(5, 6) treat as xs:integer?", ElementPathTypeError)

        self.check_value("5 treat as empty-sequence()", ElementPathTypeError)
        self.check_value("() treat as empty-sequence()", [])

    def test_castable_expression(self):
        self.check_value("5 castable as xs:integer", True)
        self.check_value("'5' castable as xs:integer", True)
        self.check_value("'hello' castable as xs:integer", False)
        self.check_value("('5', '6') castable as xs:integer", False)
        self.check_value("() castable as xs:integer", False)
        self.check_value("() castable as xs:integer?", True)

    def test_cast_expression(self):
        self.check_value("5 cast as xs:integer", 5)
        self.check_value("'5' cast as xs:integer", 5)
        self.check_value("'hello' cast as xs:integer", ValueError)
        self.check_value("('5', '6') cast as xs:integer", TypeError)
        self.check_value("() cast as xs:integer", TypeError)
        self.check_value("() cast as xs:integer?", [])
        self.check_value('"1" cast as xs:boolean', True)
        self.check_value('"0" cast as xs:boolean', False)

    def test_issue_10(self):
        schema = xmlschema.XMLSchema('''
            <xs:schema xmlns="http://xpath.test/ns#" xmlns:xs="http://www.w3.org/2001/XMLSchema"
                    targetNamespace="http://xpath.test/ns#">
                <xs:element name="root" type="rootType" />
                <xs:simpleType name="rootType">
                    <xs:restriction base="xs:string"/>
                </xs:simpleType>
            </xs:schema>''')

        root = schema.find('root')
        self.assertEqual(getattr(root, 'tag', None),
                         '{http://xpath.test/ns#}root')
    def test_elements_type(self):
        schema = xmlschema.XMLSchema('''
            <xs:schema xmlns="http://xpath.test/ns" xmlns:xs="http://www.w3.org/2001/XMLSchema"
                    targetNamespace="http://xpath.test/ns">
                <xs:element name="values">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="a" type="xs:string"/>
                            <xs:element name="b" type="xs:integer"/>
                            <xs:element name="c" type="xs:boolean"/>
                            <xs:element name="d" type="xs:float"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:schema>''')
        parser = XPath2Parser(namespaces={
            '': "http://xpath.test/ns",
            'xs': XSD_NAMESPACE
        },
                              schema=XMLSchemaProxy(schema))
        token = parser.parse("//a")
        self.assertEqual(token[0].xsd_type,
                         schema.maps.types['{%s}string' % XSD_NAMESPACE])
        token = parser.parse("//b")
        self.assertEqual(token[0].xsd_type,
                         schema.maps.types['{%s}integer' % XSD_NAMESPACE])
        token = parser.parse("//values/c")
        self.assertEqual(token[0][0].xsd_type, schema.elements['values'].type)
        self.assertEqual(token[1].xsd_type,
                         schema.maps.types['{%s}boolean' % XSD_NAMESPACE])
        token = parser.parse("values/c")
        self.assertEqual(token[0].xsd_type, schema.elements['values'].type)
        self.assertEqual(token[1].xsd_type,
                         schema.maps.types['{%s}boolean' % XSD_NAMESPACE])

        schema = xmlschema.XMLSchema('''
            <xs:schema xmlns="http://xpath.test/ns" xmlns:xs="http://www.w3.org/2001/XMLSchema"
                    targetNamespace="http://xpath.test/ns">
                <xs:element name="values">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="a" type="xs:string"/>
                            <xs:element name="b" type="rangeType"/>
                            <xs:element name="c" type="xs:boolean"/>
                            <xs:element name="d" type="xs:float"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:complexType name="rangeType">
                    <xs:simpleContent>
                        <xs:extension base="xs:integer">
                            <xs:attribute name="min" type="xs:integer"/>
                            <xs:attribute name="max" type="xs:integer"/>
                        </xs:extension>
                    </xs:simpleContent>
                </xs:complexType>
            </xs:schema>''')
        parser = XPath2Parser(namespaces={
            '': "http://xpath.test/ns",
            'xs': XSD_NAMESPACE
        },
                              schema=XMLSchemaProxy(schema))
        token = parser.parse("//a")
        self.assertEqual(token[0].xsd_type,
                         schema.maps.types['{%s}string' % XSD_NAMESPACE])
        token = parser.parse("//b")
        self.assertEqual(token[0].xsd_type, schema.types['rangeType'])
        token = parser.parse("values/c")
        self.assertEqual(token[0].xsd_type, schema.elements['values'].type)
        self.assertEqual(token[1].xsd_type,
                         schema.maps.types['{%s}boolean' % XSD_NAMESPACE])
        token = parser.parse("//b/@min")
        self.assertEqual(token[0][0].xsd_type, schema.types['rangeType'])
        self.assertEqual(token[1][0].xsd_type,
                         schema.maps.types['{%s}integer' % XSD_NAMESPACE])
        token = parser.parse("values/b/@min")
        self.assertEqual(token[0][0].xsd_type, schema.elements['values'].type)
        self.assertEqual(token[0][1].xsd_type, schema.types['rangeType'])
        self.assertEqual(token[1][0].xsd_type,
                         schema.maps.types['{%s}integer' % XSD_NAMESPACE])

        token = parser.parse("//b/@min lt //b/@max")
        self.assertEqual(token[0][0][0].xsd_type, schema.types['rangeType'])
        self.assertEqual(token[0][1][0].xsd_type,
                         schema.maps.types['{%s}integer' % XSD_NAMESPACE])
        self.assertEqual(token[1][0][0].xsd_type, schema.types['rangeType'])
        self.assertEqual(token[1][1][0].xsd_type,
                         schema.maps.types['{%s}integer' % XSD_NAMESPACE])

        root = self.etree.XML(
            '<values xmlns="http://xpath.test/ns"><b min="19"/></values>')
        with self.assertRaises(TypeError):
            token.evaluate(context=XPathContext(root))

        root = self.etree.XML(
            '<values xmlns="http://xpath.test/ns"><b min="19">30</b></values>')
        self.assertIsNone(token.evaluate(context=XPathContext(root)))

        root = self.etree.XML(
            '<values xmlns="http://xpath.test/ns"><b min="19" max="40">30</b></values>'
        )
        context = XPathContext(root)
        self.assertTrue(token.evaluate(context))

        root = self.etree.XML(
            '<values xmlns="http://xpath.test/ns"><b min="19" max="10">30</b></values>'
        )
        context = XPathContext(root)
        self.assertFalse(token.evaluate(context))
Exemple #20
0
 def test_get_context_method(self):
     schema_proxy = XMLSchemaProxy(self.xs1)
     context = schema_proxy.get_context()
     self.assertIs(context.root, self.xs1)
 def test_cast_as_api(self):
     schema_proxy = XMLSchemaProxy()
     self.assertEqual(
         schema_proxy.cast_as('19', '{%s}short' % XSD_NAMESPACE), 19)
Exemple #22
0
 def test_find_method(self):
     schema_proxy = XMLSchemaProxy(self.xs1)
     qname = '{%s}cars' % self.xs1.target_namespace
     self.assertIs(schema_proxy.find(qname), self.xs1.elements['cars'])
    def test_get_primitive_type_api(self):
        schema_proxy = XMLSchemaProxy()
        short_type = schema_proxy.get_type('{%s}short' % XSD_NAMESPACE)
        decimal_type = schema_proxy.get_type('{%s}decimal' % XSD_NAMESPACE)
        self.assertEqual(schema_proxy.get_primitive_type(short_type),
                         decimal_type)

        ntokens_type = schema_proxy.get_type('{%s}NMTOKENS' % XSD_NAMESPACE)
        string_type = schema_proxy.get_type('{%s}string' % XSD_NAMESPACE)
        self.assertEqual(schema_proxy.get_primitive_type(ntokens_type),
                         string_type)

        facet_type = schema_proxy.get_type('{%s}facet' % XSD_NAMESPACE)
        any_type = schema_proxy.get_type('{%s}anyType' % XSD_NAMESPACE)
        self.assertEqual(schema_proxy.get_primitive_type(facet_type), any_type)
        self.assertEqual(schema_proxy.get_primitive_type(any_type), any_type)

        any_simple_type = schema_proxy.get_type('{%s}anySimpleType' %
                                                XSD_NAMESPACE)
        self.assertEqual(schema_proxy.get_primitive_type(any_simple_type),
                         any_simple_type)
 def test_get_type_api(self):
     schema_proxy = XMLSchemaProxy()
     self.assertIsNone(schema_proxy.get_type('unknown'))
     self.assertEqual(schema_proxy.get_type('{%s}string' % XSD_NAMESPACE),
                      xmlschema.XMLSchema.builtin_types()['string'])
 def test_get_context_method(self):
     schema_proxy = XMLSchemaProxy()
     self.assertIsInstance(schema_proxy.get_context(), XPathContext)
     self.assertIsInstance(
         super(XMLSchemaProxy, schema_proxy).get_context(), XPathContext)
Exemple #26
0
 def test_is_instance_method(self):
     schema_proxy = XMLSchemaProxy(self.xs1)
     type_qname = '{%s}string' % self.xs1.meta_schema.target_namespace
     self.assertFalse(schema_proxy.is_instance(10, type_qname))
     self.assertTrue(schema_proxy.is_instance('10', type_qname))
class XMLSchemaProxyTest(xpath_test_class.XPathTestCase):
    @classmethod
    def setUpClass(cls):
        cls.schema = xmlschema.XMLSchema('''
        <!-- Dummy schema for testing proxy API -->
        <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
              targetNamespace="http://xpath.test/ns">
          <xs:element name="test_element" type="xs:string"/>
          <xs:attribute name="test_attribute" type="xs:string"/>
          <xs:element name="A">
            <xs:complexType>
              <xs:sequence>
                <xs:element name="B1"/>
                <xs:element name="B2"/>
                <xs:element name="B3"/>
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        </xs:schema>''')

    def setUp(self):
        self.schema_proxy = XMLSchemaProxy(self.schema)
        self.parser = XPath2Parser(namespaces=self.namespaces,
                                   schema=self.schema_proxy)

    def test_abstract_xsd_schema(self):
        class GlobalMaps:
            types = {}
            attributes = {}
            elements = {}
            substitution_groups = {}

        class XsdSchema:
            tag = '{%s}schema' % XSD_NAMESPACE
            xsd_version = '1.1'
            maps = GlobalMaps()
            text = None

            @property
            def attrib(self):
                return {}

            def __iter__(self):
                return iter(())

            def find(self, path, namespaces=None):
                return

        schema = XsdSchema()
        self.assertEqual(schema.tag,
                         '{http://www.w3.org/2001/XMLSchema}schema')
        self.assertIsNone(schema.text)

    def test_schema_proxy_init(self):
        schema_src = """<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
                            <xs:element name="test_element" type="xs:string"/>
                        </xs:schema>"""
        schema_tree = ElementTree.parse(io.StringIO(schema_src))

        self.assertIsInstance(XMLSchemaProxy(), XMLSchemaProxy)
        self.assertIsInstance(XMLSchemaProxy(xmlschema.XMLSchema(schema_src)),
                              XMLSchemaProxy)
        with self.assertRaises(TypeError):
            XMLSchemaProxy(schema=schema_tree)
        with self.assertRaises(TypeError):
            XMLSchemaProxy(schema=xmlschema.XMLSchema(schema_src),
                           base_element=schema_tree)
        with self.assertRaises(TypeError):
            XMLSchemaProxy(schema=xmlschema.XMLSchema(schema_src),
                           base_element=schema_tree.getroot())

        schema = xmlschema.XMLSchema(schema_src)
        with self.assertRaises(ValueError):
            XMLSchemaProxy(base_element=schema.elements['test_element'])

    def test_xmlschema_proxy(self):
        context = XPathContext(root=self.etree.XML(
            '<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"/>'))

        self.wrong_syntax("schema-element(*)")
        self.wrong_name("schema-element(nil)")
        self.wrong_name("schema-element(xs:string)")
        self.check_value("schema-element(xs:complexType)", MissingContextError)
        self.check_value("self::schema-element(xs:complexType)", NameError,
                         context)
        self.check_value("self::schema-element(xs:schema)", [context.item],
                         context)
        self.check_tree("schema-element(xs:group)",
                        '(schema-element (: (xs) (group)))')

        attribute = context.item = AttributeNode(XML_LANG, 'en')
        self.wrong_syntax("schema-attribute(*)")
        self.wrong_name("schema-attribute(nil)")
        self.wrong_name("schema-attribute(xs:string)")
        self.check_value("schema-attribute(xml:lang)", MissingContextError)
        self.check_value("schema-attribute(xml:lang)", NameError, context)
        self.check_value("self::schema-attribute(xml:lang)", [context.item],
                         context)
        self.check_tree("schema-attribute(xsi:schemaLocation)",
                        '(schema-attribute (: (xsi) (schemaLocation)))')

        token = self.parser.parse("self::schema-attribute(xml:lang)")
        context.item = attribute
        context.axis = 'attribute'
        self.assertEqual(list(token.select(context)), [context.item])

    def test_bind_parser_method(self):
        schema_src = dedent("""
            <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
                <xs:simpleType name="stringType">
                    <xs:restriction base="xs:string"/>
                </xs:simpleType>
            </xs:schema>""")
        schema = xmlschema.XMLSchema(schema_src)

        schema_proxy = XMLSchemaProxy(schema=schema)
        parser = XPath2Parser(namespaces=self.namespaces)
        self.assertFalse(parser.is_schema_bound())

        schema_proxy.bind_parser(parser)
        self.assertTrue(parser.is_schema_bound())
        self.assertIs(schema_proxy, parser.schema)

        # To test AbstractSchemaProxy.bind_parser()
        parser = XPath2Parser(namespaces=self.namespaces)
        super(XMLSchemaProxy, schema_proxy).bind_parser(parser)
        self.assertIs(schema_proxy, parser.schema)
        super(XMLSchemaProxy, schema_proxy).bind_parser(parser)
        self.assertIs(schema_proxy, parser.schema)

    def test_schema_constructors(self):
        schema_src = dedent("""
            <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
                <xs:simpleType name="stringType">
                    <xs:restriction base="xs:string"/>
                </xs:simpleType>
                <xs:simpleType name="intType">
                    <xs:restriction base="xs:int"/>
                </xs:simpleType>
            </xs:schema>""")
        schema = xmlschema.XMLSchema(schema_src)
        schema_proxy = XMLSchemaProxy(schema=schema)
        parser = XPath2Parser(namespaces=self.namespaces, schema=schema_proxy)

        with self.assertRaises(NameError) as ctx:
            parser.schema_constructor(XSD_ANY_ATOMIC_TYPE)
        self.assertIn('XPST0080', str(ctx.exception))

        with self.assertRaises(NameError) as ctx:
            parser.schema_constructor(XSD_NOTATION)
        self.assertIn('XPST0080', str(ctx.exception))

        token = parser.parse('stringType("apple")')
        self.assertEqual(token.symbol, 'stringType')
        self.assertEqual(token.label, 'constructor function')
        self.assertEqual(token.evaluate(), 'apple')

        token = parser.parse('stringType(())')
        self.assertEqual(token.symbol, 'stringType')
        self.assertEqual(token.label, 'constructor function')
        self.assertEqual(token.evaluate(), [])

        token = parser.parse('stringType(10)')
        self.assertEqual(token.symbol, 'stringType')
        self.assertEqual(token.label, 'constructor function')
        self.assertEqual(token.evaluate(), '10')

        token = parser.parse('stringType(.)')
        self.assertEqual(token.symbol, 'stringType')
        self.assertEqual(token.label, 'constructor function')

        token = parser.parse('intType(10)')
        self.assertEqual(token.symbol, 'intType')
        self.assertEqual(token.label, 'constructor function')
        self.assertEqual(token.evaluate(), 10)

        with self.assertRaises(ValueError) as ctx:
            parser.parse('intType(true())')
        self.assertIn('FORG0001', str(ctx.exception))

    def test_get_context_method(self):
        schema_proxy = XMLSchemaProxy()
        self.assertIsInstance(schema_proxy.get_context(), XPathContext)
        self.assertIsInstance(
            super(XMLSchemaProxy, schema_proxy).get_context(), XPathContext)

    def test_get_type_api(self):
        schema_proxy = XMLSchemaProxy()
        self.assertIsNone(schema_proxy.get_type('unknown'))
        self.assertEqual(schema_proxy.get_type('{%s}string' % XSD_NAMESPACE),
                         xmlschema.XMLSchema.builtin_types()['string'])

    def test_xsd_version_api(self):
        self.assertEqual(self.schema_proxy.xsd_version, '1.0')

    def test_find_api(self):
        schema_src = """<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
                            <xs:element name="test_element" type="xs:string"/>
                        </xs:schema>"""
        schema = xmlschema.XMLSchema(schema_src)
        schema_proxy = XMLSchemaProxy(schema=schema)
        self.assertEqual(schema_proxy.find('/test_element'),
                         schema.elements['test_element'])

    def test_get_attribute_api(self):
        self.assertIs(
            self.schema_proxy.get_attribute(
                "{http://xpath.test/ns}test_attribute"), self.schema_proxy.
            _schema.maps.attributes["{http://xpath.test/ns}test_attribute"])

    def test_get_element_api(self):
        self.assertIs(
            self.schema_proxy.get_element(
                "{http://xpath.test/ns}test_element"), self.schema_proxy.
            _schema.maps.elements["{http://xpath.test/ns}test_element"])

    def test_get_substitution_group_api(self):
        self.assertIsNone(self.schema_proxy.get_substitution_group('x'))

    def test_is_instance_api(self):
        self.assertFalse(
            self.schema_proxy.is_instance(True, '{%s}integer' % XSD_NAMESPACE))
        self.assertTrue(
            self.schema_proxy.is_instance(5, '{%s}integer' % XSD_NAMESPACE))
        self.assertFalse(
            self.schema_proxy.is_instance('alpha',
                                          '{%s}integer' % XSD_NAMESPACE))
        self.assertTrue(
            self.schema_proxy.is_instance('alpha',
                                          '{%s}string' % XSD_NAMESPACE))
        self.assertTrue(
            self.schema_proxy.is_instance('alpha beta',
                                          '{%s}token' % XSD_NAMESPACE))
        self.assertTrue(
            self.schema_proxy.is_instance('alpha', '{%s}Name' % XSD_NAMESPACE))
        self.assertFalse(
            self.schema_proxy.is_instance('alpha beta',
                                          '{%s}Name' % XSD_NAMESPACE))
        self.assertFalse(
            self.schema_proxy.is_instance('1alpha',
                                          '{%s}Name' % XSD_NAMESPACE))
        self.assertTrue(
            self.schema_proxy.is_instance('alpha',
                                          '{%s}NCName' % XSD_NAMESPACE))
        self.assertFalse(
            self.schema_proxy.is_instance('eg:alpha',
                                          '{%s}NCName' % XSD_NAMESPACE))

    def test_cast_as_api(self):
        schema_proxy = XMLSchemaProxy()
        self.assertEqual(
            schema_proxy.cast_as('19', '{%s}short' % XSD_NAMESPACE), 19)

    def test_attributes_type(self):
        parser = XPath2Parser(namespaces=self.namespaces)
        token = parser.parse("@min le @max")

        context = XPathContext(self.etree.XML('<root min="10" max="20" />'))
        self.assertTrue(token.evaluate(context))

        context = XPathContext(self.etree.XML('<root min="10" max="2" />'))
        self.assertTrue(token.evaluate(context))

        schema = xmlschema.XMLSchema('''
            <xs:schema xmlns="http://xpath.test/ns" xmlns:xs="http://www.w3.org/2001/XMLSchema"
                targetNamespace="http://xpath.test/ns">
              <xs:element name="range" type="intRange"/>
              <xs:complexType name="intRange">
                <xs:attribute name="min" type="xs:int"/>
                <xs:attribute name="max" type="xs:int"/>
              </xs:complexType>
            </xs:schema>''')
        parser = XPath2Parser(namespaces=self.namespaces,
                              schema=XMLSchemaProxy(schema,
                                                    schema.elements['range']))
        token = parser.parse("@min le @max")

        context = XPathContext(self.etree.XML('<root min="10" max="20" />'))
        self.assertTrue(token.evaluate(context))
        context = XPathContext(self.etree.XML('<root min="10" max="2" />'))
        self.assertFalse(token.evaluate(context))

        schema = xmlschema.XMLSchema('''
            <xs:schema xmlns="http://xpath.test/ns" xmlns:xs="http://www.w3.org/2001/XMLSchema"
                targetNamespace="http://xpath.test/ns">
              <xs:element name="range" type="intRange"/>
              <xs:complexType name="intRange">
                <xs:attribute name="min" type="xs:int"/>
                <xs:attribute name="max" type="xs:string"/>
              </xs:complexType>
            </xs:schema>''')
        parser = XPath2Parser(namespaces=self.namespaces,
                              schema=XMLSchemaProxy(schema,
                                                    schema.elements['range']))
        self.assertRaises(TypeError, parser.parse, '@min le @max')

    def test_elements_type(self):
        schema = xmlschema.XMLSchema('''
            <xs:schema xmlns="http://xpath.test/ns" xmlns:xs="http://www.w3.org/2001/XMLSchema"
                    targetNamespace="http://xpath.test/ns">
                <xs:element name="values">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="a" type="xs:string"/>
                            <xs:element name="b" type="xs:integer"/>
                            <xs:element name="c" type="xs:boolean"/>
                            <xs:element name="d" type="xs:float"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:schema>''')
        parser = XPath2Parser(namespaces={
            '': "http://xpath.test/ns",
            'xs': XSD_NAMESPACE
        },
                              schema=XMLSchemaProxy(schema))

        token = parser.parse("//a")
        self.assertEqual(token[0].xsd_types['a'],
                         schema.maps.types['{%s}string' % XSD_NAMESPACE])
        token = parser.parse("//b")
        self.assertEqual(token[0].xsd_types['b'],
                         schema.maps.types['{%s}integer' % XSD_NAMESPACE])
        token = parser.parse("//values/c")

        self.assertEqual(token[0][0].xsd_types["{http://xpath.test/ns}values"],
                         schema.elements['values'].type)
        self.assertEqual(token[1].xsd_types['c'],
                         schema.maps.types['{%s}boolean' % XSD_NAMESPACE])

        token = parser.parse("values/c")
        self.assertEqual(token[0].xsd_types['{http://xpath.test/ns}values'],
                         schema.elements['values'].type)
        self.assertEqual(token[1].xsd_types['c'],
                         schema.maps.types['{%s}boolean' % XSD_NAMESPACE])

        token = parser.parse("values/*")
        self.assertEqual(
            token[1].xsd_types, {
                'a': schema.maps.types['{%s}string' % XSD_NAMESPACE],
                'b': schema.maps.types['{%s}integer' % XSD_NAMESPACE],
                'c': schema.maps.types['{%s}boolean' % XSD_NAMESPACE],
                'd': schema.maps.types['{%s}float' % XSD_NAMESPACE],
            })

    def test_elements_and_attributes_type(self):
        schema = xmlschema.XMLSchema('''
            <xs:schema xmlns="http://xpath.test/ns" xmlns:xs="http://www.w3.org/2001/XMLSchema"
                    targetNamespace="http://xpath.test/ns">
                <xs:element name="values">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="a" type="xs:string"/>
                            <xs:element name="b" type="rangeType"/>
                            <xs:element name="c" type="xs:boolean"/>
                            <xs:element name="d" type="xs:float"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:complexType name="rangeType">
                    <xs:simpleContent>
                        <xs:extension base="xs:integer">
                            <xs:attribute name="min" type="xs:integer"/>
                            <xs:attribute name="max" type="xs:integer"/>
                        </xs:extension>
                    </xs:simpleContent>
                </xs:complexType>
            </xs:schema>''')
        parser = XPath2Parser(namespaces={
            '': "http://xpath.test/ns",
            'xs': XSD_NAMESPACE
        },
                              schema=XMLSchemaProxy(schema))
        token = parser.parse("//a")
        self.assertEqual(token[0].xsd_types['a'],
                         schema.maps.types['{%s}string' % XSD_NAMESPACE])
        token = parser.parse("//b")
        self.assertEqual(token[0].xsd_types['b'], schema.types['rangeType'])
        token = parser.parse("values/c")

        self.assertEqual(token[0].xsd_types['{http://xpath.test/ns}values'],
                         schema.elements['values'].type)
        self.assertEqual(token[1].xsd_types['c'],
                         schema.maps.types['{%s}boolean' % XSD_NAMESPACE])
        token = parser.parse("//b/@min")
        self.assertEqual(token[0][0].xsd_types['b'], schema.types['rangeType'])

        self.assertEqual(token[1][0].xsd_types['min'],
                         schema.maps.types['{%s}integer' % XSD_NAMESPACE])

        token = parser.parse("values/b/@min")
        self.assertEqual(token[0][0].xsd_types['{http://xpath.test/ns}values'],
                         schema.elements['values'].type)
        self.assertEqual(token[0][1].xsd_types['b'], schema.types['rangeType'])
        self.assertEqual(token[1][0].xsd_types['min'],
                         schema.maps.types['{%s}integer' % XSD_NAMESPACE])

        token = parser.parse("//b/@min lt //b/@max")
        self.assertEqual(token[0][0][0].xsd_types['b'],
                         schema.types['rangeType'])
        self.assertEqual(token[0][1][0].xsd_types['min'],
                         schema.maps.types['{%s}integer' % XSD_NAMESPACE])
        self.assertEqual(token[1][0][0].xsd_types['b'],
                         schema.types['rangeType'])
        self.assertEqual(token[1][1][0].xsd_types['max'],
                         schema.maps.types['{%s}integer' % XSD_NAMESPACE])

        root = self.etree.XML(
            '<values xmlns="http://xpath.test/ns"><b min="19"/></values>')
        context = XPathContext(root, namespaces={'': "http://xpath.test/ns"})
        self.assertIsNone(token.evaluate(context))

        root = self.etree.XML(
            '<values xmlns="http://xpath.test/ns"><b min="19">30</b></values>')
        context = XPathContext(root, namespaces={'': "http://xpath.test/ns"})
        self.assertIsNone(token.evaluate(context))

        root = self.etree.XML(
            '<values xmlns="http://xpath.test/ns"><b min="19" max="40">30</b></values>'
        )
        context = XPathContext(root, namespaces={'': "http://xpath.test/ns"})
        self.assertTrue(token.evaluate(context))

        root = self.etree.XML(
            '<values xmlns="http://xpath.test/ns"><b min="19" max="10">30</b></values>'
        )
        context = XPathContext(root, namespaces={'': "http://xpath.test/ns"})
        self.assertFalse(token.evaluate(context))

    def test_issue_10(self):
        schema = xmlschema.XMLSchema('''
            <xs:schema xmlns="http://xpath.test/ns#" xmlns:xs="http://www.w3.org/2001/XMLSchema"
                    targetNamespace="http://xpath.test/ns#">
                <xs:element name="root" type="rootType" />
                <xs:simpleType name="rootType">
                    <xs:restriction base="xs:string"/>
                </xs:simpleType>
            </xs:schema>''')

        # TODO: test fail with xmlschema-1.0.17+, added namespaces as temporary fix for test.
        #  A fix for xmlschema.xpath.ElementPathMixin._get_xpath_namespaces() is required.
        root = schema.find('root', namespaces={'': 'http://xpath.test/ns#'})
        self.assertEqual(getattr(root, 'tag', None),
                         '{http://xpath.test/ns#}root')
Exemple #28
0
 def test_cast_as_method(self):
     schema_proxy = XMLSchemaProxy(self.xs1)
     type_qname = '{%s}short' % self.xs1.meta_schema.target_namespace
     self.assertEqual(schema_proxy.cast_as('10', type_qname), 10)