pyRdfa.property
Implementation of the C{@property} value handling.
RDFa 1.0 and RDFa 1.1 are fairly different. RDFa 1.0 generates only literals, see U{RDFa Task Force's wiki pagehttp://www.w3.org/2006/07/SWD/wiki/RDFa/LiteralObject} for the details. On the other hand, RDFa 1.1, beyond literals, can also generate URI references. Hence the duplicate method in the L{ProcessProperty} class, one for RDFa 1.0 and the other for RDFa 1.1.
@summary: RDFa Literal generation
@requires: U{RDFLib packagehttp://rdflib.net}
@organization: U{World Wide Web Consortiumhttp://www.w3.org}
@author: U{Ivan Herman}
@license: This software is available for use under the
U{W3C® SOFTWARE NOTICE AND LICENSE
1# -*- coding: utf-8 -*- 2""" 3Implementation of the C{@property} value handling. 4 5RDFa 1.0 and RDFa 1.1 are fairly different. RDFa 1.0 generates only literals, see 6U{RDFa Task Force's wiki page<http://www.w3.org/2006/07/SWD/wiki/RDFa/LiteralObject>} for the details. 7On the other hand, RDFa 1.1, beyond literals, can also generate URI references. Hence the duplicate method in the L{ProcessProperty} class, one for RDFa 1.0 and the other for RDFa 1.1. 8 9@summary: RDFa Literal generation 10@requires: U{RDFLib package<http://rdflib.net>} 11@organization: U{World Wide Web Consortium<http://www.w3.org>} 12@author: U{Ivan Herman<a href="http://www.w3.org/People/Ivan/">} 13@license: This software is available for use under the 14U{W3C® SOFTWARE NOTICE AND LICENSE<href="http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231">} 15""" 16 17""" 18$Id: property.py,v 1.14 2013-07-26 16:10:16 ivan Exp $ 19$Date: 2013-07-26 16:10:16 $ 20""" 21 22from rdflib import BNode 23from rdflib import Literal, URIRef 24from rdflib import RDF as ns_rdf 25from rdflib.term import XSDToPython 26 27from . import IncorrectBlankNodeUsage, IncorrectLiteral, err_no_blank_node 28from .utils import has_one_of_attributes, return_XML 29 30import re 31 32XMLLiteral = ns_rdf["XMLLiteral"] 33HTMLLiteral = URIRef("http://www.w3.org/1999/02/22-rdf-syntax-ns#HTML") 34 35class ProcessProperty: 36 """Generate the value for C{@property} taking into account datatype, etc. 37 Note: this class is created only if the C{@property} is indeed present, no need to check. 38 39 @ivar node: DOM element node 40 @ivar graph: the (RDF) graph to add the properies to 41 @ivar subject: the RDFLib URIRef serving as a subject for the generated triples 42 @ivar state: the current state to be used for the CURIE-s 43 @type state: L{state.ExecutionContext} 44 @ivar typed_resource: Typically the bnode generated by a @typeof 45 """ 46 def __init__(self, node, graph, subject, state, typed_resource=None): 47 """ 48 @param node: DOM element node 49 @param graph: the (RDF) graph to add the properies to 50 @param subject: the RDFLib URIRef serving as a subject for the generated triples 51 @param state: the current state to be used for the CURIE-s 52 @param state: L{state.ExecutionContext} 53 @param typed_resource: Typically the bnode generated by a @typeof; in RDFa 1.1, that becomes the object for C{@property} 54 """ 55 self.node = node 56 self.graph = graph 57 self.subject = subject 58 self.state = state 59 self.typed_resource = typed_resource 60 61 def generate(self): 62 """ 63 Common entry point for the RDFa 1.0 and RDFa 1.1 versions; bifurcates based on the RDFa version, as retrieved from the state object. 64 """ 65 if self.state.rdfa_version >= "1.1": 66 self.generate_1_1() 67 else: 68 self.generate_1_0() 69 70 def generate_1_1(self): 71 """Generate the property object, 1.1 version""" 72 73 ######################################################################### 74 # See if the target is _not_ a literal 75 irirefs = ("resource", "href", "src") 76 noiri = ("content", "datatype", "rel", "rev") 77 notypediri = ("content", "datatype", "rel", "rev", "about", "about_pruned") 78 if has_one_of_attributes(self.node, irirefs) and not has_one_of_attributes(self.node, noiri): 79 # @href/@resource/@src takes the lead here... 80 obj = self.state.getResource(irirefs) 81 elif self.node.hasAttribute("typeof") and not has_one_of_attributes(self.node, notypediri) and self.typed_resource != None: 82 # a @typeof creates a special branch in case the typed resource was set during parsing 83 obj = self.typed_resource 84 else: 85 # We have to generate a literal 86 87 # Get, if exists, the value of @datatype 88 datatype = '' 89 dtset = False 90 if self.node.hasAttribute("datatype"): 91 dtset = True 92 dt = self.node.getAttribute("datatype") 93 if dt != "": 94 datatype = self.state.getURI("datatype") 95 96 # Supress lange is set in case some elements explicitly want to supress the effect of language 97 # There were discussions, for example, that the <time> element should do so. Although, 98 # after all, this was reversed, the functionality is kept in the code in case another 99 # element might need it... 100 if self.state.lang != None and self.state.supress_lang == False: 101 lang = self.state.lang 102 else: 103 lang = '' 104 105 # The simple case: separate @content attribute 106 if self.node.hasAttribute("content"): 107 val = self.node.getAttribute("content") 108 # Handling the automatic uri conversion case 109 if dtset == False: 110 obj = Literal(val, lang=lang) 111 else: 112 obj = self._create_Literal(val, datatype=datatype, lang=lang) 113 # The value of datatype has been set, and the keyword paramaters take care of the rest 114 else: 115 # see if there *is* a datatype (even if it is empty!) 116 if dtset: 117 if datatype == XMLLiteral: 118 litval = self._get_XML_literal(self.node) 119 obj = Literal(litval,datatype=XMLLiteral) 120 elif datatype == HTMLLiteral: 121 # I am not sure why this hack is necessary, but otherwise an encoding error occurs 122 # In Python3 all this should become moot, due to the unicode everywhere approach... 123 obj = Literal(self._get_HTML_literal(self.node), datatype=HTMLLiteral) 124 else: 125 obj = self._create_Literal(self._get_literal(self.node), datatype=datatype, lang=lang) 126 else: 127 obj = self._create_Literal(self._get_literal(self.node), lang=lang) 128 129 if obj != None: 130 for prop in self.state.getURI("property"): 131 if not isinstance(prop, BNode): 132 if self.node.hasAttribute("inlist"): 133 self.state.add_to_list_mapping(prop, obj) 134 else : 135 self.graph.add( (self.subject, prop, obj) ) 136 else: 137 self.state.options.add_warning(err_no_blank_node % "property", warning_type=IncorrectBlankNodeUsage, node=self.node.nodeName) 138 139 # return 140 141 def generate_1_0(self): 142 """Generate the property object, 1.0 version""" 143 144 ######################################################################### 145 # We have to generate a literal indeed. 146 # Get, if exists, the value of @datatype 147 datatype = '' 148 dtset = False 149 if self.node.hasAttribute("datatype"): 150 dtset = True 151 dt = self.node.getAttribute("datatype") 152 if dt != "": 153 datatype = self.state.getURI("datatype") 154 155 if self.state.lang != None: 156 lang = self.state.lang 157 else: 158 lang = '' 159 160 # The simple case: separate @content attribute 161 if self.node.hasAttribute("content"): 162 val = self.node.getAttribute("content") 163 # Handling the automatic uri conversion case 164 if dtset == False: 165 obj = Literal(val, lang=lang) 166 else: 167 obj = self._create_Literal(val, datatype=datatype, lang=lang) 168 # The value of datatype has been set, and the keyword paramaters take care of the rest 169 else: 170 # see if there *is* a datatype (even if it is empty!) 171 if dtset: 172 # yep. The Literal content is the pure text part of the current element: 173 # We have to check whether the specified datatype is, in fact, an 174 # explicit XML Literal 175 if datatype == XMLLiteral: 176 litval = self._get_XML_literal(self.node) 177 obj = Literal(litval,datatype=XMLLiteral) 178 elif datatype == HTMLLiteral: 179 # I am not sure why this hack is necessary, but otherwise an encoding error occurs 180 # In Python3 all this should become moot, due to the unicode everywhere approach... 181 obj = Literal(self._get_HTML_literal(self.node), datatype=HTMLLiteral) 182 else: 183 obj = self._create_Literal(self._get_literal(self.node), datatype=datatype, lang=lang) 184 else: 185 # no controlling @datatype. We have to see if there is markup in the contained 186 # element 187 if True in [ n.nodeType == self.node.ELEMENT_NODE for n in self.node.childNodes ]: 188 # yep, and XML Literal should be generated 189 obj = self._create_Literal(self._get_XML_literal(self.node), datatype=XMLLiteral) 190 else: 191 # At this point, there might be entities in the string that are returned as real characters by the dom 192 # implementation. That should be turned back 193 obj = self._create_Literal(self._get_literal(self.node), lang=lang) 194 195 for prop in self.state.getURI("property"): 196 if not isinstance(prop,BNode): 197 self.graph.add( (self.subject,prop,obj) ) 198 else: 199 self.state.options.add_warning(err_no_blank_node % "property", warning_type=IncorrectBlankNodeUsage, node=self.node.nodeName) 200 201 # return 202 203 ###################################################################################################################################### 204 205 206 def _putBackEntities(self, data): 207 """Put 'back' entities for the '&','<', and '>' characters, to produce a proper XML string. 208 Used by the XML Literal extraction. 209 @param data: string to be converted 210 @return: string with entities 211 @rtype: string 212 """ 213 return data.replace('&','&').replace('<','<').replace('>','>') 214 215 def _get_literal(self, Pnode): 216 """ 217 Get (recursively) the full text from a DOM Node. 218 219 @param Pnode: DOM Node 220 @return: string 221 """ 222 rc = "" 223 for node in Pnode.childNodes: 224 if node.nodeType == node.TEXT_NODE: 225 rc = rc + node.data 226 elif node.nodeType == node.ELEMENT_NODE: 227 rc = rc + self._get_literal(node) 228 229 # The decision of the group in February 2008 is not to normalize the result by default. 230 # This is reflected in the default value of the option 231 232 if self.state.options.space_preserve: 233 return rc 234 else: 235 return re.sub(r'(\r| |\n|\t)+'," ",rc).strip() 236 # end getLiteral 237 238 def _get_XML_literal(self, Pnode): 239 """ 240 Get (recursively) the XML Literal content of a DOM Node. 241 242 @param Pnode: DOM Node 243 @return: string 244 """ 245 rc = "" 246 for node in Pnode.childNodes: 247 if node.nodeType == node.TEXT_NODE: 248 rc = rc + self._putBackEntities(node.data) 249 elif node.nodeType == node.ELEMENT_NODE: 250 rc = rc + return_XML(self.state, node, base = False) 251 return rc 252 # end getXMLLiteral 253 254 def _get_HTML_literal(self, Pnode): 255 """ 256 Get (recursively) the XML Literal content of a DOM Node. 257 258 @param Pnode: DOM Node 259 @return: string 260 """ 261 rc = "" 262 for node in Pnode.childNodes: 263 if node.nodeType == node.TEXT_NODE: 264 rc = rc + self._putBackEntities(node.data) 265 elif node.nodeType == node.ELEMENT_NODE: 266 rc = rc + return_XML(self.state, node, base = False, xmlns = False ) 267 return rc 268 # end getHTMLLLiteral 269 270 def _create_Literal(self, val, datatype = '', lang = ''): 271 """ 272 Create a literal, taking into account the datatype and language. 273 @return: Literal 274 """ 275 if datatype == None or datatype == '': 276 return Literal(val, lang=lang) 277 #elif datatype == ns_xsd["string"]: 278 # return Literal(val) 279 else: 280 # This is a bit convoluted... the default setup of rdflib does not gracefully react if the 281 # datatype cannot properly be converted to Python. I have to copy and reuse some of the 282 # rdflib code to get this working... 283 # To make things worse: rdlib 3.1.0 does not handle the various xsd date types properly, ie, 284 # the conversion function below will generate errors. Ie, the check should be skipped for those 285 convFunc = XSDToPython.get(datatype, None) 286 if convFunc: 287 try: 288 _pv = convFunc(val) 289 # If we got there the literal value and its datatype match 290 except: 291 self.state.options.add_warning("Incompatible value (%s) and datatype (%s) in Literal definition." % (val, datatype), warning_type=IncorrectLiteral, node=self.node.nodeName) 292 return Literal(val, datatype=datatype)
36class ProcessProperty: 37 """Generate the value for C{@property} taking into account datatype, etc. 38 Note: this class is created only if the C{@property} is indeed present, no need to check. 39 40 @ivar node: DOM element node 41 @ivar graph: the (RDF) graph to add the properies to 42 @ivar subject: the RDFLib URIRef serving as a subject for the generated triples 43 @ivar state: the current state to be used for the CURIE-s 44 @type state: L{state.ExecutionContext} 45 @ivar typed_resource: Typically the bnode generated by a @typeof 46 """ 47 def __init__(self, node, graph, subject, state, typed_resource=None): 48 """ 49 @param node: DOM element node 50 @param graph: the (RDF) graph to add the properies to 51 @param subject: the RDFLib URIRef serving as a subject for the generated triples 52 @param state: the current state to be used for the CURIE-s 53 @param state: L{state.ExecutionContext} 54 @param typed_resource: Typically the bnode generated by a @typeof; in RDFa 1.1, that becomes the object for C{@property} 55 """ 56 self.node = node 57 self.graph = graph 58 self.subject = subject 59 self.state = state 60 self.typed_resource = typed_resource 61 62 def generate(self): 63 """ 64 Common entry point for the RDFa 1.0 and RDFa 1.1 versions; bifurcates based on the RDFa version, as retrieved from the state object. 65 """ 66 if self.state.rdfa_version >= "1.1": 67 self.generate_1_1() 68 else: 69 self.generate_1_0() 70 71 def generate_1_1(self): 72 """Generate the property object, 1.1 version""" 73 74 ######################################################################### 75 # See if the target is _not_ a literal 76 irirefs = ("resource", "href", "src") 77 noiri = ("content", "datatype", "rel", "rev") 78 notypediri = ("content", "datatype", "rel", "rev", "about", "about_pruned") 79 if has_one_of_attributes(self.node, irirefs) and not has_one_of_attributes(self.node, noiri): 80 # @href/@resource/@src takes the lead here... 81 obj = self.state.getResource(irirefs) 82 elif self.node.hasAttribute("typeof") and not has_one_of_attributes(self.node, notypediri) and self.typed_resource != None: 83 # a @typeof creates a special branch in case the typed resource was set during parsing 84 obj = self.typed_resource 85 else: 86 # We have to generate a literal 87 88 # Get, if exists, the value of @datatype 89 datatype = '' 90 dtset = False 91 if self.node.hasAttribute("datatype"): 92 dtset = True 93 dt = self.node.getAttribute("datatype") 94 if dt != "": 95 datatype = self.state.getURI("datatype") 96 97 # Supress lange is set in case some elements explicitly want to supress the effect of language 98 # There were discussions, for example, that the <time> element should do so. Although, 99 # after all, this was reversed, the functionality is kept in the code in case another 100 # element might need it... 101 if self.state.lang != None and self.state.supress_lang == False: 102 lang = self.state.lang 103 else: 104 lang = '' 105 106 # The simple case: separate @content attribute 107 if self.node.hasAttribute("content"): 108 val = self.node.getAttribute("content") 109 # Handling the automatic uri conversion case 110 if dtset == False: 111 obj = Literal(val, lang=lang) 112 else: 113 obj = self._create_Literal(val, datatype=datatype, lang=lang) 114 # The value of datatype has been set, and the keyword paramaters take care of the rest 115 else: 116 # see if there *is* a datatype (even if it is empty!) 117 if dtset: 118 if datatype == XMLLiteral: 119 litval = self._get_XML_literal(self.node) 120 obj = Literal(litval,datatype=XMLLiteral) 121 elif datatype == HTMLLiteral: 122 # I am not sure why this hack is necessary, but otherwise an encoding error occurs 123 # In Python3 all this should become moot, due to the unicode everywhere approach... 124 obj = Literal(self._get_HTML_literal(self.node), datatype=HTMLLiteral) 125 else: 126 obj = self._create_Literal(self._get_literal(self.node), datatype=datatype, lang=lang) 127 else: 128 obj = self._create_Literal(self._get_literal(self.node), lang=lang) 129 130 if obj != None: 131 for prop in self.state.getURI("property"): 132 if not isinstance(prop, BNode): 133 if self.node.hasAttribute("inlist"): 134 self.state.add_to_list_mapping(prop, obj) 135 else : 136 self.graph.add( (self.subject, prop, obj) ) 137 else: 138 self.state.options.add_warning(err_no_blank_node % "property", warning_type=IncorrectBlankNodeUsage, node=self.node.nodeName) 139 140 # return 141 142 def generate_1_0(self): 143 """Generate the property object, 1.0 version""" 144 145 ######################################################################### 146 # We have to generate a literal indeed. 147 # Get, if exists, the value of @datatype 148 datatype = '' 149 dtset = False 150 if self.node.hasAttribute("datatype"): 151 dtset = True 152 dt = self.node.getAttribute("datatype") 153 if dt != "": 154 datatype = self.state.getURI("datatype") 155 156 if self.state.lang != None: 157 lang = self.state.lang 158 else: 159 lang = '' 160 161 # The simple case: separate @content attribute 162 if self.node.hasAttribute("content"): 163 val = self.node.getAttribute("content") 164 # Handling the automatic uri conversion case 165 if dtset == False: 166 obj = Literal(val, lang=lang) 167 else: 168 obj = self._create_Literal(val, datatype=datatype, lang=lang) 169 # The value of datatype has been set, and the keyword paramaters take care of the rest 170 else: 171 # see if there *is* a datatype (even if it is empty!) 172 if dtset: 173 # yep. The Literal content is the pure text part of the current element: 174 # We have to check whether the specified datatype is, in fact, an 175 # explicit XML Literal 176 if datatype == XMLLiteral: 177 litval = self._get_XML_literal(self.node) 178 obj = Literal(litval,datatype=XMLLiteral) 179 elif datatype == HTMLLiteral: 180 # I am not sure why this hack is necessary, but otherwise an encoding error occurs 181 # In Python3 all this should become moot, due to the unicode everywhere approach... 182 obj = Literal(self._get_HTML_literal(self.node), datatype=HTMLLiteral) 183 else: 184 obj = self._create_Literal(self._get_literal(self.node), datatype=datatype, lang=lang) 185 else: 186 # no controlling @datatype. We have to see if there is markup in the contained 187 # element 188 if True in [ n.nodeType == self.node.ELEMENT_NODE for n in self.node.childNodes ]: 189 # yep, and XML Literal should be generated 190 obj = self._create_Literal(self._get_XML_literal(self.node), datatype=XMLLiteral) 191 else: 192 # At this point, there might be entities in the string that are returned as real characters by the dom 193 # implementation. That should be turned back 194 obj = self._create_Literal(self._get_literal(self.node), lang=lang) 195 196 for prop in self.state.getURI("property"): 197 if not isinstance(prop,BNode): 198 self.graph.add( (self.subject,prop,obj) ) 199 else: 200 self.state.options.add_warning(err_no_blank_node % "property", warning_type=IncorrectBlankNodeUsage, node=self.node.nodeName) 201 202 # return 203 204 ###################################################################################################################################### 205 206 207 def _putBackEntities(self, data): 208 """Put 'back' entities for the '&','<', and '>' characters, to produce a proper XML string. 209 Used by the XML Literal extraction. 210 @param data: string to be converted 211 @return: string with entities 212 @rtype: string 213 """ 214 return data.replace('&','&').replace('<','<').replace('>','>') 215 216 def _get_literal(self, Pnode): 217 """ 218 Get (recursively) the full text from a DOM Node. 219 220 @param Pnode: DOM Node 221 @return: string 222 """ 223 rc = "" 224 for node in Pnode.childNodes: 225 if node.nodeType == node.TEXT_NODE: 226 rc = rc + node.data 227 elif node.nodeType == node.ELEMENT_NODE: 228 rc = rc + self._get_literal(node) 229 230 # The decision of the group in February 2008 is not to normalize the result by default. 231 # This is reflected in the default value of the option 232 233 if self.state.options.space_preserve: 234 return rc 235 else: 236 return re.sub(r'(\r| |\n|\t)+'," ",rc).strip() 237 # end getLiteral 238 239 def _get_XML_literal(self, Pnode): 240 """ 241 Get (recursively) the XML Literal content of a DOM Node. 242 243 @param Pnode: DOM Node 244 @return: string 245 """ 246 rc = "" 247 for node in Pnode.childNodes: 248 if node.nodeType == node.TEXT_NODE: 249 rc = rc + self._putBackEntities(node.data) 250 elif node.nodeType == node.ELEMENT_NODE: 251 rc = rc + return_XML(self.state, node, base = False) 252 return rc 253 # end getXMLLiteral 254 255 def _get_HTML_literal(self, Pnode): 256 """ 257 Get (recursively) the XML Literal content of a DOM Node. 258 259 @param Pnode: DOM Node 260 @return: string 261 """ 262 rc = "" 263 for node in Pnode.childNodes: 264 if node.nodeType == node.TEXT_NODE: 265 rc = rc + self._putBackEntities(node.data) 266 elif node.nodeType == node.ELEMENT_NODE: 267 rc = rc + return_XML(self.state, node, base = False, xmlns = False ) 268 return rc 269 # end getHTMLLLiteral 270 271 def _create_Literal(self, val, datatype = '', lang = ''): 272 """ 273 Create a literal, taking into account the datatype and language. 274 @return: Literal 275 """ 276 if datatype == None or datatype == '': 277 return Literal(val, lang=lang) 278 #elif datatype == ns_xsd["string"]: 279 # return Literal(val) 280 else: 281 # This is a bit convoluted... the default setup of rdflib does not gracefully react if the 282 # datatype cannot properly be converted to Python. I have to copy and reuse some of the 283 # rdflib code to get this working... 284 # To make things worse: rdlib 3.1.0 does not handle the various xsd date types properly, ie, 285 # the conversion function below will generate errors. Ie, the check should be skipped for those 286 convFunc = XSDToPython.get(datatype, None) 287 if convFunc: 288 try: 289 _pv = convFunc(val) 290 # If we got there the literal value and its datatype match 291 except: 292 self.state.options.add_warning("Incompatible value (%s) and datatype (%s) in Literal definition." % (val, datatype), warning_type=IncorrectLiteral, node=self.node.nodeName) 293 return Literal(val, datatype=datatype)
Generate the value for C{@property} taking into account datatype, etc. Note: this class is created only if the C{@property} is indeed present, no need to check.
@ivar node: DOM element node @ivar graph: the (RDF) graph to add the properies to @ivar subject: the RDFLib URIRef serving as a subject for the generated triples @ivar state: the current state to be used for the CURIE-s @type state: L{state.ExecutionContext} @ivar typed_resource: Typically the bnode generated by a @typeof
47 def __init__(self, node, graph, subject, state, typed_resource=None): 48 """ 49 @param node: DOM element node 50 @param graph: the (RDF) graph to add the properies to 51 @param subject: the RDFLib URIRef serving as a subject for the generated triples 52 @param state: the current state to be used for the CURIE-s 53 @param state: L{state.ExecutionContext} 54 @param typed_resource: Typically the bnode generated by a @typeof; in RDFa 1.1, that becomes the object for C{@property} 55 """ 56 self.node = node 57 self.graph = graph 58 self.subject = subject 59 self.state = state 60 self.typed_resource = typed_resource
@param node: DOM element node @param graph: the (RDF) graph to add the properies to @param subject: the RDFLib URIRef serving as a subject for the generated triples @param state: the current state to be used for the CURIE-s @param state: L{state.ExecutionContext} @param typed_resource: Typically the bnode generated by a @typeof; in RDFa 1.1, that becomes the object for C{@property}
62 def generate(self): 63 """ 64 Common entry point for the RDFa 1.0 and RDFa 1.1 versions; bifurcates based on the RDFa version, as retrieved from the state object. 65 """ 66 if self.state.rdfa_version >= "1.1": 67 self.generate_1_1() 68 else: 69 self.generate_1_0()
Common entry point for the RDFa 1.0 and RDFa 1.1 versions; bifurcates based on the RDFa version, as retrieved from the state object.
71 def generate_1_1(self): 72 """Generate the property object, 1.1 version""" 73 74 ######################################################################### 75 # See if the target is _not_ a literal 76 irirefs = ("resource", "href", "src") 77 noiri = ("content", "datatype", "rel", "rev") 78 notypediri = ("content", "datatype", "rel", "rev", "about", "about_pruned") 79 if has_one_of_attributes(self.node, irirefs) and not has_one_of_attributes(self.node, noiri): 80 # @href/@resource/@src takes the lead here... 81 obj = self.state.getResource(irirefs) 82 elif self.node.hasAttribute("typeof") and not has_one_of_attributes(self.node, notypediri) and self.typed_resource != None: 83 # a @typeof creates a special branch in case the typed resource was set during parsing 84 obj = self.typed_resource 85 else: 86 # We have to generate a literal 87 88 # Get, if exists, the value of @datatype 89 datatype = '' 90 dtset = False 91 if self.node.hasAttribute("datatype"): 92 dtset = True 93 dt = self.node.getAttribute("datatype") 94 if dt != "": 95 datatype = self.state.getURI("datatype") 96 97 # Supress lange is set in case some elements explicitly want to supress the effect of language 98 # There were discussions, for example, that the <time> element should do so. Although, 99 # after all, this was reversed, the functionality is kept in the code in case another 100 # element might need it... 101 if self.state.lang != None and self.state.supress_lang == False: 102 lang = self.state.lang 103 else: 104 lang = '' 105 106 # The simple case: separate @content attribute 107 if self.node.hasAttribute("content"): 108 val = self.node.getAttribute("content") 109 # Handling the automatic uri conversion case 110 if dtset == False: 111 obj = Literal(val, lang=lang) 112 else: 113 obj = self._create_Literal(val, datatype=datatype, lang=lang) 114 # The value of datatype has been set, and the keyword paramaters take care of the rest 115 else: 116 # see if there *is* a datatype (even if it is empty!) 117 if dtset: 118 if datatype == XMLLiteral: 119 litval = self._get_XML_literal(self.node) 120 obj = Literal(litval,datatype=XMLLiteral) 121 elif datatype == HTMLLiteral: 122 # I am not sure why this hack is necessary, but otherwise an encoding error occurs 123 # In Python3 all this should become moot, due to the unicode everywhere approach... 124 obj = Literal(self._get_HTML_literal(self.node), datatype=HTMLLiteral) 125 else: 126 obj = self._create_Literal(self._get_literal(self.node), datatype=datatype, lang=lang) 127 else: 128 obj = self._create_Literal(self._get_literal(self.node), lang=lang) 129 130 if obj != None: 131 for prop in self.state.getURI("property"): 132 if not isinstance(prop, BNode): 133 if self.node.hasAttribute("inlist"): 134 self.state.add_to_list_mapping(prop, obj) 135 else : 136 self.graph.add( (self.subject, prop, obj) ) 137 else: 138 self.state.options.add_warning(err_no_blank_node % "property", warning_type=IncorrectBlankNodeUsage, node=self.node.nodeName) 139 140 # return
Generate the property object, 1.1 version
142 def generate_1_0(self): 143 """Generate the property object, 1.0 version""" 144 145 ######################################################################### 146 # We have to generate a literal indeed. 147 # Get, if exists, the value of @datatype 148 datatype = '' 149 dtset = False 150 if self.node.hasAttribute("datatype"): 151 dtset = True 152 dt = self.node.getAttribute("datatype") 153 if dt != "": 154 datatype = self.state.getURI("datatype") 155 156 if self.state.lang != None: 157 lang = self.state.lang 158 else: 159 lang = '' 160 161 # The simple case: separate @content attribute 162 if self.node.hasAttribute("content"): 163 val = self.node.getAttribute("content") 164 # Handling the automatic uri conversion case 165 if dtset == False: 166 obj = Literal(val, lang=lang) 167 else: 168 obj = self._create_Literal(val, datatype=datatype, lang=lang) 169 # The value of datatype has been set, and the keyword paramaters take care of the rest 170 else: 171 # see if there *is* a datatype (even if it is empty!) 172 if dtset: 173 # yep. The Literal content is the pure text part of the current element: 174 # We have to check whether the specified datatype is, in fact, an 175 # explicit XML Literal 176 if datatype == XMLLiteral: 177 litval = self._get_XML_literal(self.node) 178 obj = Literal(litval,datatype=XMLLiteral) 179 elif datatype == HTMLLiteral: 180 # I am not sure why this hack is necessary, but otherwise an encoding error occurs 181 # In Python3 all this should become moot, due to the unicode everywhere approach... 182 obj = Literal(self._get_HTML_literal(self.node), datatype=HTMLLiteral) 183 else: 184 obj = self._create_Literal(self._get_literal(self.node), datatype=datatype, lang=lang) 185 else: 186 # no controlling @datatype. We have to see if there is markup in the contained 187 # element 188 if True in [ n.nodeType == self.node.ELEMENT_NODE for n in self.node.childNodes ]: 189 # yep, and XML Literal should be generated 190 obj = self._create_Literal(self._get_XML_literal(self.node), datatype=XMLLiteral) 191 else: 192 # At this point, there might be entities in the string that are returned as real characters by the dom 193 # implementation. That should be turned back 194 obj = self._create_Literal(self._get_literal(self.node), lang=lang) 195 196 for prop in self.state.getURI("property"): 197 if not isinstance(prop,BNode): 198 self.graph.add( (self.subject,prop,obj) ) 199 else: 200 self.state.options.add_warning(err_no_blank_node % "property", warning_type=IncorrectBlankNodeUsage, node=self.node.nodeName) 201 202 # return
Generate the property object, 1.0 version