def testInfiniteElement(self): """ Test parsing an EBML file with an infinite-length element. """ schemaFile = './schemata/matroska.xml' ebmlFile1 = './tests/video-2.mkv' ebmlFile2 = './tests/video-3.mkv' schema = core.loadSchema(schemaFile) # Convert the MKV files into human-readable xml strings ebmlDoc1 = schema.load(ebmlFile1, headers=True) ebmlRoot1 = util.toXml(ebmlDoc1) xmlString1 = ET.tostring(ebmlRoot1, encoding='UTF-8').replace('><', '>\r\n<') ebmlDoc2 = schema.load(ebmlFile2, headers=True) ebmlRoot2 = util.toXml(ebmlDoc2) xmlString2 = ET.tostring(ebmlRoot2, encoding='UTF-8').replace('><', '>\r\n<') # Convert the xml strings into lists of lines to make comparison easier, # dropping the second line because that will reference different source # file names xmlLines1 = xmlString1.splitlines() xmlLines1 = [xmlLines1[0]] + xmlLines1[2:] xmlLines2 = xmlString2.splitlines() xmlLines2 = [xmlLines2[0]] + xmlLines2[2:] # Compare as lists to narrow the location of any differences self.assertListEqual( xmlLines1, xmlLines2, 'One or more lines are different in the xml documents')
def setUp(self): """ Set up a Schema from mide_ide.xml and create a Document from an IDE file. """ self.schema = loadSchema('./schemata/mide_ide.xml') self.doc = self.schema.load('./tests/SSX46714-doesnot.IDE') self.stream = StringIO('test')
def setUp(self): """ Set up the unit tests with a generic Element class with some custom data (id: 0x4F56, value: 0x71EA). """ # set element as: # id: 00 1111 0101 0110 # value: 11 0001 1110 1010 # header: 0100 1111 0101 0110 # data: 0111 0001 1110 1010 self.mockStream = StringIO('\x4f\x56\x71\xea') GenericElement = type( 'GenericElement', (Element, ), { 'id': 0x4343, 'name': 'Generic Element', 'schema': loadSchema('./schemata/mide_ide.xml'), 'mandatory': False, 'multiple': False, 'precache': False, 'length': 4, 'children': dict(), '__doc__': 'no' }) self.element = GenericElement(stream=self.mockStream, offset=0, size=4, payloadOffset=2)
def setUp(self): """ Set up a new Schema. It is necessary to clear the cache to properly run tests. """ import core core.SCHEMATA = {} self.schema = loadSchema('./schemata/mide_ide.xml') self.stream = StringIO('test')
def setUp(self): """ Set up a MasterElement with a single UIntegerElement child. """ schema = loadSchema('./schemata/mide_ide.xml') """ Master Element: ID: 0x1A45DFA3 Size: 0x84 Value: UInt Element: ID: 0x4286 Size: 0x81 value: 0x42 """ self.mockStream = StringIO('\x1A\x45\xDF\xA3\x84\x42\x86\x81\x10') self.element = schema.elements[0x1A45DFA3](stream=self.mockStream, offset=0, size=4, payloadOffset=5) self.element.schema = loadSchema('./schemata/mide_ide.xml') self.element.id = 0x1A45DFA3
def testMkv(self): """ Test the functionality of the ebmlite library by converting a known good MKV file (a derivative of EBML) back and forth, then compare the results. """ schemaFile = './schemata/matroska.xml' ebmlFile1 = './tests/video-1.mkv' ebmlFile2 = './tests/video-2.mkv' xmlFile1 = './tests/video-1.xml' xmlFile2 = './tests/video-2.xml' schema = core.loadSchema(schemaFile) # Start with toXml ebmlDoc1 = schema.load(ebmlFile1, headers=True) ebmlRoot = util.toXml(ebmlDoc1) xmlString1 = ET.tostring(ebmlRoot, encoding='UTF-8') # Save xml with open(xmlFile1, 'wt') as f: f.write(xmlString1) # Convert xml2ebml with open(ebmlFile2, 'wb') as out: util.xml2ebml(xmlFile1, out, schema) # write the second xml file ebmlDoc2 = schema.load(ebmlFile2, headers=True) mkvRoot2 = util.toXml(ebmlDoc2) xmlString2 = ET.tostring(mkvRoot2, encoding='UTF-8') # self.assertEqual(xmlString1, xmlString2, "xml strings aren't matching up") with open(xmlFile2, 'wt') as f: f.write(xmlString2) # Load back the XML files in order to compare the two xmlDoc1 = util.loadXml(xmlFile1, schema) xmlDoc2 = util.loadXml(xmlFile2, schema) # Compare each element from the XML xmlEls1 = [xmlDoc1] xmlEls2 = [xmlDoc2] while len(xmlEls1) > 0: self.assertEqual( xmlEls1[0], xmlEls2[0], 'Element ' + repr(xmlEls1[0]) + ' was not converted properly') for x in xmlEls1.pop(0).children.values(): if issubclass(x, core.Element): xmlEls1.append(x) for x in xmlEls2.pop(0).children.values(): if issubclass(x, core.Element): xmlEls2.append(x)
def testPPrint(self): """ Test pretty-printing EBML files. """ schemaFile = './schemata/mide_ide.xml' schema = core.loadSchema(schemaFile) ebmlDoc = schema.load('./tests/SSX46714-doesnot.IDE', headers=True) util.pprint(ebmlDoc, out=open('./tests/IDE-Pretty.txt', 'wt')) xmlString = ET.tostring(util.toXml(ebmlDoc)) prettyXmlFile = open('./tests/IDE-Pretty.xml', 'wt') parseString(xmlString).writexml(prettyXmlFile, addindent='\t', newl='\n', encoding='utf-8')
def testParse(self): """ Test parsing MasterElements. """ masterEl = MasterElement() masterEl.id = 0x1A45DFA3 masterEl.size = 4 masterEl.schema = loadSchema('./schemata/mide_ide.xml') self.assertEqual(masterEl, self.element) sEbmlVer = self.element.parse()[0] sEbmlVer.stream = self.mockStream ebmlVer = masterEl.schema.elements[0x4286](masterEl.stream, 5, 1, 8) ebmlVer.stream = self.mockStream ebmlVer._value = 16 self.assertEqual(sEbmlVer, ebmlVer)
def xml2ebml(xmlFile, ebmlFile, schema, sizeLength=None, headers=True, unknown=True): """ Convert an XML file to EBML. @todo: Convert XML on the fly, rather than parsing it first, allowing for the conversion of arbitrarily huge files. @param xmlFile: The XML source. Can be a filename, an open file-like stream, or a parsed XML document. @param ebmlFile: The EBML file to write. Can be a filename or an open file-like stream. @param schema: The EBML schema to use. Can be a filename or an instance of a `Schema`. @keyword sizeLength: The default length of each element's size descriptor. Must be large enough to store the largest 'master' element. If an XML element has a ``sizeLength`` attribute, it will override this. @keyword headers: If `True`, generate the standard ``EBML`` EBML element if the XML document does not contain one. @param unknown: If `True`, unknown element names will be allowed, provided their XML elements include an ``id`` attribute with the EBML ID (in hexadecimal). @return: the size of the ebml file in bytes. @raise NameError: raises if an xml element is not present in the schema. """ if isinstance(ebmlFile, basestring): ebmlFile = open(ebmlFile, 'wb') openedEbml = True else: openedEbml = False if not isinstance(schema, core.Schema): schema = core.loadSchema(schema) if isinstance(xmlFile, ET.Element): # Already a parsed XML element xmlRoot = xmlFile elif isinstance(xmlFile, ET.ElementTree): # Already a parsed XML document xmlRoot = xmlFile.getroot() else: xmlDoc = ET.parse(xmlFile) xmlRoot = xmlDoc.getroot() if xmlRoot.tag not in schema and xmlRoot.tag != schema.document.__name__: raise NameError("XML element %s not an element or document in " "schema %s (wrong schema)" % (xmlRoot.tag, schema.name)) headers = headers and 'EBML' in schema if headers and 'EBML' not in (el.tag for el in xmlRoot): pos = ebmlFile.tell() cls = schema.document ebmlFile.write(cls.encodePayload(cls._createHeaders())) numBytes = ebmlFile.tell() - pos else: numBytes = 0 if xmlRoot.tag == schema.document.__name__: for el in xmlRoot: numBytes += xmlElement2ebml(el, ebmlFile, schema, sizeLength, unknown=unknown) else: numBytes += xmlElement2ebml(xmlRoot, ebmlFile, schema, sizeLength, unknown=unknown) if openedEbml: ebmlFile.close() return numBytes
'--clobber', action="store_true", help="Clobber (overwrite) existing files.") argparser.add_argument('-p', '--pretty', action="store_true", help="Generate 'pretty' XML with ebml2xml.") args = argparser.parse_args() if not os.path.exists(args.input): sys.stderr.write("Input file does not exist: %s\n" % args.input) exit(1) try: schema = core.loadSchema(args.schema) except IOError as err: errPrint("Error loading schema: %s\n" % err) if args.output: output = os.path.realpath(os.path.expanduser(args.output)) if os.path.exists(output) and not args.clobber: errPrint("Output file exists: %s" % args.output) out = open(output, 'wb') else: out = sys.stdout if args.mode == "xml2ebml": xml2ebml(args.input, out, schema) # , sizeLength=4, headers=True, unknown=True) elif args.mode == "ebml2xml":
# imports from python's built in xml library from xml.etree import ElementTree as ET from xml.dom.minidom import parseString # ======================================= # converting a file from EBML to XML # ======================================= # Files to use in this example schemaFile = './schemata/mide_ide.xml' ebmlFile1 = './tests/SSX46714-doesnot.IDE' xmlFile1 = './tests/example-xml.xml' # load the schema to use with these files. This creates an object that is used # to parse EBML files. schema = core.loadSchema(schemaFile) # Convert the EBML file to XML ebmlDoc1 = schema.load(ebmlFile1, headers=True) # load the file through # the schema ebmlRoot = toXml(ebmlDoc1) # convert the file into # a tree of XML elements xmlString1 = ET.tostring(ebmlRoot, encoding='UTF-8') # convert the xml tree # into a string # Save xml with open(xmlFile1, 'wt') as f: # convert the xml string into a minidom object and pretty-print f.write(parseString(xmlString1).toprettyxml(indent=' ')) # =======================================