########################################################################
# $Header: /var/local/cvsroot/4Suite/Ft/Xml/_4xml.py,v 1.27.2.1 2006/10/16 21:52:38 jkloth Exp $
"""
Implementation of '4xml' command
(functions defined here are used by the Ft.Lib.CommandLine framework)
Copyright 2006 Fourthought, Inc. (USA).
Detailed license and copyright information: http://4suite.org/COPYRIGHT
Project home, documentation, distributions: http://4suite.org/
"""
import os, sys
from Ft.Lib import CloseStream
from Ft.Lib.CommandLine import CommandLineApp,Options,Arguments
from Ft.Lib.CommandLine.CommandLineUtil import SourceArgToInputSource
from Ft.Xml import InputSource
class XmlCommandLineApp(CommandLineApp.CommandLineApp):
from Ft.__config__ import \
NAME as project_name, VERSION as project_version, URL as project_url
name = '4xml'
summary = 'command-line tool for working with XML documents'
description = """4XML command-line application"""
options = [
Options.Option(
'v', 'validate',
'DTD validate the input file as it is being parsed'),
Options.Option(
'e', 'encoding=ENC',
'The encoding to use for output'),
Options.Option(
None, 'input-encoding=ENC',
'The encoding to assume for input'),
Options.Option(
'o', 'outfile=FILE',
'Direct output to FILE (file will be overwritten if it exists)'),
Options.Option(
'p', 'pretty',
'Pretty-print the result'),
Options.Option(
'n', 'noserialize',
"Do not serialize; just parse"),
Options.Option(
None, 'html',
'Use HTML mode when pretty-printing (emit XHTML as HTML)'),
Options.Option(
None, 'noxinclude',
'Do not expand XIncludes'),
Options.Option(
None, 'rng=FILE',
'Apply RELAX NG from the given file (technically RNG with XVIF'
' features)'),
]
arguments = [
Arguments.RequiredArgument(
'source-uri',
'The URI of the XML document to parse, or "-" to indicate standard'
' input.'),
]
def validate_arguments(self, args):
if not args:
raise SystemExit('A source URI argument is required.' \
' See "%s -h" for usage info.' % sys.argv[0])
return CommandLineApp.CommandLineApp.validate_arguments(self, args)
def run(self, options, arguments):
return Run(options, arguments)
def Run(options, args):
xinclude = not options.has_key('noxinclude')
noserialize = options.has_key('noserialize')
out_file = options.has_key('outfile') and open(options['outfile'], 'w') or sys.stdout
validate_flag = options.has_key('validate')
pretty = options.has_key('pretty')
as_html = options.has_key('html')
encoding = options.get('encoding', 'utf-8')
input_encoding = options.get('input-encoding', None)
rng_sourceUri = options.get('rng')
sourceUri = args['source-uri']
try:
source_isrc = SourceArgToInputSource(sourceUri,
InputSource.DefaultFactory,
processIncludes=xinclude, encoding=input_encoding)
rng_isrc = None
if rng_sourceUri:
rng_isrc = SourceArgToInputSource(rng_sourceUri,
InputSource.DefaultFactory,
processIncludes=xinclude, encoding=input_encoding)
except Exception, e:
sys.stderr.write(str(e)+'\n')
sys.stderr.flush()
return
if rng_isrc is not None:
try:
from Ft.Xml.Xvif import RelaxNgValidator,RngInvalid
except ImportError:
raise SystemExit("Missing RELAX-NG support library. It is "
"available in the Ft.Xml.ThirdParty package.")
from Ft.Xml import Domlette
if validate_flag:
reader = Domlette.ValidatingReader
else:
reader = Domlette.NonvalidatingReader
try:
doc = reader.parse(source_isrc)
CloseStream(source_isrc, quiet=True)
if rng_isrc is not None:
validator = RelaxNgValidator(rng_isrc)
CloseStream(rng_isrc, quiet=True)
result = validator.validateNode(doc)
if not result.nullable():
raise RngInvalid(result)
if not noserialize:
from Ft.Xml.Domlette import Print,PrettyPrint
if pretty:
PrettyPrint(doc, out_file, encoding, as_html)
else:
Print(doc, out_file, encoding, as_html)
except Exception, e:
import traceback
traceback.print_exc(1000, sys.stderr)
raise
try:
if out_file.isatty():
out_file.flush()
sys.stderr.write('\n')
else:
out_file.close()
except (IOError, ValueError):
pass
return
|