[PATCH seda] [profile gen] Systematically turn IDREF into NCName in SEDA 2.0 RNG export

Sylvain Thenault sylvain.thenault at logilab.fr
Fri May 19 10:36:37 CEST 2017


# HG changeset patch
# User Sylvain Thénault <sylvain.thenault at logilab.fr>
# Date 1495141303 -7200
#      Thu May 18 23:01:43 2017 +0200
# Node ID 67558c0fc5ee8628956bdda371aa3c6e408198e7
# Parent  7319f0d205c4ba2a1c599413a4a1988a79f08264
# Available At https://hg.logilab.org/review/cubes/seda
#              hg pull https://hg.logilab.org/review/cubes/seda -r 67558c0fc5ee
[profile gen] Systematically turn IDREF into NCName in SEDA 2.0 RNG export


RNG doesn't handle ID/IDREF as XSD: it doesn't handle having some tag's
*content* of such type, as it is the case in SEDA 2 ObjectReferenceId element.
See https://www.oasis-open.org/committees/relax-ng/compatibility.html#id for
details.

To fix this, 'downgrade' ID into NCName. This was already done when some data
object was referenced, but it should actually be done systematically.

Closes #17078970

diff --git a/cubicweb_seda/entities/profile_generation.py b/cubicweb_seda/entities/profile_generation.py
--- a/cubicweb_seda/entities/profile_generation.py
+++ b/cubicweb_seda/entities/profile_generation.py
@@ -65,10 +65,12 @@ def content_types(content_type):
     """
     if content_type:
         if isinstance(content_type, set):
             content_types = sorted(content_type)
         else:
+            if content_type == 'IDREF':
+                content_type = 'NCName'
             content_types = (content_type,)
     else:
         content_types = ()
     return content_types
 
@@ -545,11 +547,11 @@ class SEDA2RelaxNGExport(RNGMixin, SEDA2
         else:
             fixed_value = serialize(value, self.cwuri_url)
         if fixed_value is not None:
             if _internal_reference(value):
                 profile_element.attrib[self.qname('a:defaultValue')] = fixed_value
-                self.element('rng:data', profile_element, {'type': 'NCName'})
+                self.element('rng:data', profile_element, {'type': xstype})
             else:
                 if (len(profile_element)
                         and profile_element[-1].tag == '{http://relaxng.org/ns/structure/1.0}data'):
                     xstype = profile_element[-1].attrib.get('type')
                     profile_element.remove(profile_element[-1])
diff --git a/test/test_profile_generation.py b/test/test_profile_generation.py
--- a/test/test_profile_generation.py
+++ b/test/test_profile_generation.py
@@ -667,11 +667,12 @@ class SEDARNGExportFuncTC(SEDAExportFunc
         # ensure they are properly referenced using 'default' attribute
         xmlid = eid2xmlid(self.bdo_eid)
         references = self.xpath(root, '//rng:element[@a:defaultValue="{}"]'.format(xmlid))
         self.assertEqual(len(references), 1)
         self.assertEqual(references[0].attrib['name'], 'DataObjectReferenceId')
-        self.assertEqual(references[0][0].attrib['type'], 'NCName')
+        for reference_id in self.xpath(root, '//rng:element[@name="DataObjectReferenceId"]'):
+            self.assertEqual(reference_id[0].attrib['type'], 'NCName')
         # ensure optional id are properly reinjected
         references = self.xpath(root,
                                 '//rng:element[@name="Keyword"]/rng:optional'
                                 '/rng:attribute[@name="id"]')
         self.assertEqual(len(references), 1)


More information about the saem-devel mailing list