def pushdom(source, xpatterns, prefixes=None, validate=False): parser = Sax.CreateParser() if validate: parser.setFeature(xml.sax.handler.feature_validation, True) else: parser.setFeature(xml.sax.handler.feature_external_pes, False) parser.setFeature(Sax.FEATURE_GENERATOR, True) def handle_chunk(docfrag): parser.setProperty(Sax.PROPERTY_YIELD_RESULT, docfrag) handler = sax2dom_chunker(xpatterns=xpatterns, nss=prefixes, chunk_consumer=handle_chunk) parser.setContentHandler(handler) if isinstance(source, InputSource.InputSource): pass elif hasattr(source, 'read'): #Create dummy Uri to use as base dummy_uri = 'urn:uuid:' + Uuid.UuidAsString(Uuid.GenerateUuid()) source = InputSource.DefaultFactory.fromStream(source, dummy_uri) elif IsXml(source): #Create dummy Uri to use as base dummy_uri = 'urn:uuid:' + Uuid.UuidAsString(Uuid.GenerateUuid()) source = InputSource.DefaultFactory.fromString(source, dummy_uri) elif Uri.IsAbsolute(source): #or not os.path.isfile(source): source = InputSource.DefaultFactory.fromUri(source) else: source = InputSource.DefaultFactory.fromUri(Uri.OsPathToUri(source)) return parser.parse(source)
def CreateInputSource(obj, uri=None): """ Convenience function for creating an InputSource. obj - a string, Unicode object (only if you really know what you're doing), file-like object (stream), file path or URI. You can also pass an InputSource object, in which case the return value is just the same object, possibly with the URI modified uri - optional override URI. The base URI for the IS will be set to this value Returns an InputSource which can be passed to 4Suite APIs. """ #do the imports within the function: a tad bit less efficient, but #avoid circular crap from Ft.Xml import InputSource factory = InputSource.DefaultFactory from Ft.Lib import Uri, Uuid from Ft.Xml.Lib.XmlString import IsXml if isinstance(obj, InputSource.InputSource): isrc = obj elif hasattr(obj, 'read'): #Create dummy Uri to use as base dummy_uri = 'urn:uuid:' + Uuid.UuidAsString(Uuid.GenerateUuid()) isrc = factory.fromStream(obj, dummy_uri) elif IsXml(obj): dummy_uri = 'urn:uuid:' + Uuid.UuidAsString(Uuid.GenerateUuid()) isrc = factory.fromString(obj, dummy_uri) elif Uri.IsAbsolute(obj): #or not os.path.isfile(obj): isrc = factory.fromUri(obj) else: isrc = factory.fromUri(Uri.OsPathToUri(obj)) if uri: isrc.uri = uri return isrc
def _AttachStylesheetToProcessor(stylesheet, processor): from Ft.Lib import Uri, Uuid from Ft.Xml import InputSource from Ft.Xml.Catalog import IsXml if isinstance(stylesheet, InputSource.InputSource): processor.appendStylesheet(stylesheet) #elif stylesheet.find(XSL_NAMESPACE) > 0 and IsXml(stylesheet): #Note: this would break in pathological cases such as a user #passing in a stylesheet string with only an XInclude to the actual XSLT elif IsXml(stylesheet): #Create dummy Uri to use as base dummy_uri = 'urn:uuid:' + Uuid.UuidAsString(Uuid.GenerateUuid()) processor.appendStylesheet( InputSource.DefaultFactory.fromString(stylesheet, dummy_uri)) elif hasattr(stylesheet, 'read'): #Create dummy Uri to use as base dummy_uri = 'urn:uuid:' + Uuid.UuidAsString(Uuid.GenerateUuid()) processor.appendStylesheet( InputSource.DefaultFactory.fromStream(stylesheet, dummy_uri)) elif Uri.IsAbsolute(stylesheet): # or not os.path.isfile(stylesheet): processor.appendStylesheet( InputSource.DefaultFactory.fromUri(stylesheet)) else: processor.appendStylesheet( InputSource.DefaultFactory.fromUri(Uri.OsPathToUri(stylesheet))) return
def ConvertDocument(oldDocument, documentURI=u''): """ Since foreign DOMs are not supported within 4Suite, this function lets users create a Domlette DOM from whatever DOM they are using. If the documentURI is not specified, it will try and get it from the document using DOM L3 attributes documentURI, then baseURI. If no URI is found, a warning is issued and a urn:uuid is generated for it. """ if not documentURI: # DOM Level 3 URI support only if hasattr(oldDocument, 'documentURI'): documentURI = oldDocument.documentURI elif hasattr(oldDocument, 'baseURI'): documentURI = oldDocument.baseURI else: from Ft.Lib import Uuid documentURI = 'urn:uuid:' + Uuid.UuidAsString(Uuid.GenerateUuid()) warnings.warn("Document created without a URI", RuntimeWarning, 2) document = implementation.createRootNode(documentURI) for oldChild in oldDocument.childNodes: child = document.importNode(oldChild, 1) document.appendChild(child) return document
def GenerateUuid(context): """ Returns a random UUID string. """ from Ft.Lib import Uuid rt = Uuid.UuidAsString(Uuid.GenerateUuid()) rt = unicode(rt, 'us-ascii', errors='replace') return rt
def ParseRDF(context, contents, type='unknown', uri=''): contents = StringValue(contents) type = StringValue(type) uri = StringValue(uri) if not uri: from Ft.Lib import Uuid uri = 'urn:uuid:' + Uuid.UuidAsString(Uuid.GenerateUuid()) nsRevMap = getattr(context.node.ownerDocument, 'nsRevMap', None) schemaClass = getattr(context.node.ownerDocument, 'schemaClass', RxPath.defaultSchemaClass) stmts = RxPath.parseRDFFromString(contents, uri, type) return [RxPath.RxPathDOMFromStatements(stmts, nsRevMap, uri, schemaClass)]
def Parse(source): """ Convenience function for parsing XML. Use this function with a single argument, which must either be a string (not Unicode object), file-like object (stream), file path or URI. Returns a Domlette node. Only pass strings or streams to this function if the XML is self-contained XML (i.e. not requiring access to any other resource such as external entities or includes). If you get URI resolution errors, do not use this function: use the lower-level APIs instead. As an example, if you want such resolution to use the current working directory as a base, parse as follows for strings: from Ft.Xml.Domlette import NonvalidatingReader from Ft.Lib import Uri XML = "<!DOCTYPE a [ <!ENTITY b "b.xml"> ]><a>&b;</a>" base = Uri.OsPathToUri('') #Turn CWD into a file: URL doc = NonvalidatingReader.parseString(XML, base) # during parsing, the replacement text for &b; # will be obtained from b.xml in the CWD For streams, use "parseStream" rather than "parseString" in the above. """ #do the imports within the function: a tad bit less efficient, but #avoid circular crap from Ft.Xml.Domlette import NonvalidatingReader from Ft.Lib import Uri, Uuid from Ft.Xml.Lib.XmlString import IsXml if hasattr(source, 'read'): #Create dummy Uri to use as base dummy_uri = 'urn:uuid:' + Uuid.UuidAsString(Uuid.GenerateUuid()) return NonvalidatingReader.parseStream(source, dummy_uri) elif IsXml(source): dummy_uri = 'urn:uuid:' + Uuid.UuidAsString(Uuid.GenerateUuid()) return NonvalidatingReader.parseString(source, dummy_uri) elif Uri.IsAbsolute(source): #or not os.path.isfile(source): return NonvalidatingReader.parseUri(source) else: return NonvalidatingReader.parseUri(Uri.OsPathToUri(source))
def Transform(source, stylesheet, params=None, output=None): """ Convenience function for applying an XSLT transform. Returns a string. source - XML source document in the form of a a string (not Unicode object), file-like object (stream), file path, URI or Ft.Xml.InputSource.InputSource instance. If string or stream it must be self-contained XML (i.e. not requiring access to any other resource such as external entities or includes) stylesheet - XSLT document in the form of a string, stream, URL, file path or Ft.Xml.InputSource.InputSource instance params - optional dictionary of stylesheet parameters, the keys of which may be given as unicode objects if they have no namespace, or as (uri, localname) tuples if they do. output - optional file-like object to which output is written (incrementally, as processed) """ #do the imports within the function: a tad bit less efficient, but #avoid circular crap from Ft.Xml.Xslt import Processor from Ft.Xml import InputSource from Ft.Lib import Uri, Uuid from Ft.Xml.Lib.XmlString import IsXml params = params or {} processor = Processor.Processor() _AttachStylesheetToProcessor(stylesheet, processor) if isinstance(source, InputSource.InputSource): pass elif hasattr(source, 'read'): #Create dummy Uri to use as base dummy_uri = 'urn:uuid:' + Uuid.UuidAsString(Uuid.GenerateUuid()) source = InputSource.DefaultFactory.fromStream(source, dummy_uri) elif IsXml(source): dummy_uri = 'urn:uuid:' + Uuid.UuidAsString(Uuid.GenerateUuid()) source = InputSource.DefaultFactory.fromString(source, dummy_uri) elif Uri.IsAbsolute(source): # or not os.path.isfile(source): source = InputSource.DefaultFactory.fromUri(source) else: source = InputSource.DefaultFactory.fromUri(Uri.OsPathToUri(source)) return processor.run(source, topLevelParams=params, outputStream=output)
def __init__(self, stream, uri=None, processIncludes=True, stripElements=None, factory=None, resolver=Uri.BASIC_RESOLVER, catalog=None, encoding=None): """ InputSource constructor source = InputSource(...) stream - the stream associated with this input source uri - the absolute URI of the input source processIncludes - Whether or not XIncludes should be expanded stripElements - Space stripping rules factory - The factory that created this instance resolver - URI resolver; defaults to Ft.Lib.Uri.BASIC_RESOLVER catalog - TR9401/XML Catalog object for resolving public IDs encoding - a string externally declaring the stream's encoding """ if uri: self.uri = uri else: self.uri = 'urn:uuid:' + Uuid.UuidAsString(Uuid.GenerateUuid()) self.stream = stream self.processIncludes = processIncludes self.stripElements = stripElements or [] self.factory = factory self.fragment = Uri.SplitFragment(self.uri)[1] self._resolver = resolver self._catalog = catalog enc = self._getStreamEncoding(stream) if enc is None: enc = encoding self.encoding = enc self.name = self.uri for name in _file_methods: method = getattr(stream, name, None) if method: setattr(self, name, method) return
def __init__(self, uri=None, string=None, baseUri='', validate=False, **kwords): self.uri = uri self.string = string self.baseUri = baseUri self.validate = validate self.args = kwords # Same logic that exists in _4xslt.py # The processor only deals with URIs, not file paths if uri and os.path.isfile(uri): self.uri = Uri.OsPathToUri(os.path.abspath(uri)) if not (uri or string): raise ValueError('Either string or uri are required') if string and not baseUri: base = os.path.join(os.path.abspath(os.getcwd()), Uuid.UuidAsString(Uuid.GenerateUuid())) self.baseUri = Uri.OsPathToUri(base) return
def GenerateUuid(context): from Ft.Lib import Uuid return Uuid.UuidAsString(Uuid.GenerateUuid())
# key() and xsl:key # format-number() and xsl:decimal-format # current() # unparsed-entity-uri() # generate-id() # system-property(), including these required properties: # system-property('xsl:version') # system-property('xsl:vendor') # system-property('xsl:vendor-url') tests = [] DUMMY_XML_STR = "<dummy/>" DUMMY_XML_URI = Uri.OsPathToUri( os.path.join(os.path.abspath(os.getcwd()), Uuid.UuidAsString(Uuid.GenerateUuid()))) TEST_XML_STR = """<?xml version="1.0"?> <doc> <elem a1="1" a2="6">one</elem> <elem a1="2" a2="4">two</elem> <elem a1="3" a2="2">three</elem> </doc>""" TEST_XML_URI = None # (one will be generated) TEST_DIR_URI_BASE = Uri.OsPathToUri(os.path.abspath(os.getcwd())) if TEST_DIR_URI_BASE[-1] != '/': TEST_DIR_URI_BASE += '/' f = open(os.path.normpath('Xml/Xslt/Core/addr_book1.xml'), 'r') ADDR_BOOK_FILE_CONTENTS = f.read()