From: Oleg T. <he...@us...> - 2005-11-16 21:51:18
|
Update of /cvsroot/mvp-xml/Common/v2/src/Xsl In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5998/v2/src/Xsl Modified Files: IXmlTransform.cs MvpXslTransform.cs Log Message: Index: MvpXslTransform.cs =================================================================== RCS file: /cvsroot/mvp-xml/Common/v2/src/Xsl/MvpXslTransform.cs,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- MvpXslTransform.cs 15 Nov 2005 22:17:25 -0000 1.3 +++ MvpXslTransform.cs 16 Nov 2005 21:51:10 -0000 1.4 @@ -10,41 +10,43 @@ namespace Mvp.Xml.Common.Xsl { public class MvpXslTransform : IXmlTransform { - XslCompiledTransform compiledTransform; + private XslCompiledTransform compiledTransform; public MvpXslTransform(XslCompiledTransform transform) { if (transform == null) throw new ArgumentNullException("transform"); this.compiledTransform = transform; } - public virtual void Transform(XmlInput defaultDocument, XsltArgumentList args, XmlOutput output) { + public void Transform(XmlInput defaultDocument, XsltArgumentList args, XmlOutput output) { + if (defaultDocument == null) throw new ArgumentNullException("defaltDocument"); XmlWriter xmlWriter = output.destination as XmlWriter; bool closeWriter = false; if (xmlWriter == null) { closeWriter = true; - - TextWriter txtWriter = output.destination as TextWriter; - if (txtWriter != null) - { - xmlWriter = XmlWriter.Create(txtWriter, this.compiledTransform.OutputSettings); - break; - } - Stream strm = output.destination as Stream; - if (strm != null) - { - xmlWriter = XmlWriter.Create(strm, this.compiledTransform.OutputSettings); - break; - } - String str = output.destination as String; - if (str != null) + while (true) { - // BugBug: We should read doc before creating output file in case they are the same - xmlWriter = XmlWriter.Create(str, this.compiledTransform.OutputSettings); - break; + TextWriter txtWriter = output.destination as TextWriter; + if (txtWriter != null) + { + xmlWriter = XmlWriter.Create(txtWriter, this.compiledTransform.OutputSettings); + break; + } + Stream strm = output.destination as Stream; + if (strm != null) + { + xmlWriter = XmlWriter.Create(strm, this.compiledTransform.OutputSettings); + break; + } + String str = output.destination as String; + if (str != null) + { + // BugBug: We should read doc before creating output file in case they are the same + xmlWriter = XmlWriter.Create(str, this.compiledTransform.OutputSettings); + break; + } + throw new Exception("Unexpected XmlOutput"); } - throw new Exception("Unexpected XmlOutput"); - } try { TransformToWriter(defaultDocument, args, xmlWriter); @@ -55,10 +57,31 @@ } } - private static XmlReaderSettings ReaderSettings; + public XmlReader Transform(XmlInput defaultDocument, XsltArgumentList args) + { + XslReader r = new XslReader(compiledTransform); + r.StartTransform(defaultDocument, args); + return r; + } + + private static XmlReaderSettings DefaultReaderSettings; static MvpXslTransform() { - ReaderSettings = new XmlReaderSettings(); - ReaderSettings.ProhibitDtd = true; + DefaultReaderSettings = new XmlReaderSettings(); + DefaultReaderSettings.ProhibitDtd = false; + } + + private XmlReaderSettings GetReaderSettings(XmlInput defaultDocument) + { + if (defaultDocument.resolver is DefaultXmlResolver) + { + return DefaultReaderSettings; + } + else + { + XmlReaderSettings settings = DefaultReaderSettings.Clone(); + settings.XmlResolver = defaultDocument.resolver; + return settings; + } } private void TransformToWriter(XmlInput defaultDocument, XsltArgumentList args, XmlWriter xmlWriter) { @@ -70,26 +93,35 @@ IXPathNavigable nav = defaultDocument.source as IXPathNavigable; if (nav != null) { - TransformIXPathNavigable(nav, args, xmlWriter, defaultDocument.resolver); + if (defaultDocument.resolver is DefaultXmlResolver) + { + compiledTransform.Transform(nav, args, xmlWriter); + } + else + { + TransformIXPathNavigable(nav, args, xmlWriter, defaultDocument.resolver); + } return; - } + } string str = defaultDocument.source as string; - if (str != null) { - using (XmlReader reader = XmlReader.Create(str, ReaderSettings)) { + if (str != null) { + using (XmlReader reader = XmlReader.Create(str, GetReaderSettings(defaultDocument))) { compiledTransform.Transform(reader, args, xmlWriter, defaultDocument.resolver); } return; } Stream strm = defaultDocument.source as Stream; if (strm != null) { - using (XmlReader reader = XmlReader.Create(strm, ReaderSettings)) { + using (XmlReader reader = XmlReader.Create(strm, GetReaderSettings(defaultDocument))) + { compiledTransform.Transform(reader, args, xmlWriter, defaultDocument.resolver); } return; } TextReader txtReader = defaultDocument.source as TextReader; if (txtReader != null) { - using (XmlReader reader = XmlReader.Create(txtReader, ReaderSettings)) { + using (XmlReader reader = XmlReader.Create(txtReader, GetReaderSettings(defaultDocument))) + { compiledTransform.Transform(reader, args, xmlWriter, defaultDocument.resolver); } return; @@ -99,11 +131,15 @@ private void TransformIXPathNavigable(IXPathNavigable nav, XsltArgumentList args, XmlWriter xmlWriter, XmlResolver resolver) { - compiledTransform.GetType().GetMethod( - compiledTransform.Transform(nav, args, xmlWriter); + object command = compiledTransform.GetType().GetField( + "command", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(compiledTransform); + MethodInfo executeMethod = command.GetType().GetMethod("Execute", BindingFlags.Instance | BindingFlags.NonPublic, + null, new Type[] { typeof(IXPathNavigable), typeof(XmlResolver), typeof(XsltArgumentList), typeof(XmlWriter) }, null); + executeMethod.Invoke(compiledTransform, + new object[] {nav, resolver, args, xmlWriter}); } - XmlWriterSettings DefaultWriterSettings { + public XmlWriterSettings DefaultWriterSettings { get { if (this.compiledTransform != null) { return this.compiledTransform.OutputSettings; Index: IXmlTransform.cs =================================================================== RCS file: /cvsroot/mvp-xml/Common/v2/src/Xsl/IXmlTransform.cs,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- IXmlTransform.cs 15 Nov 2005 22:17:25 -0000 1.2 +++ IXmlTransform.cs 16 Nov 2005 21:51:10 -0000 1.3 @@ -7,24 +7,106 @@ #endregion namespace Mvp.Xml.Common.Xsl { + + /// <summary> + /// New experimental generic XML transform interface. Defines an API for + /// transforming <see cref="XmlInput"/> into <see cref="XmlOutput"/>. + /// </summary> public interface IXmlTransform { + /// <summary> + /// Transforms given <see cref="XmlInput"/> into <see cref="XmlOutput"/>. + /// </summary> + /// <param name="defaulDocument">Default input XML document</param> + /// <param name="args">Parameters</param> + /// <param name="output">Represents the transformation's output</param> void Transform(XmlInput defaulDocument, XsltArgumentList args, XmlOutput output); + /// <summary> + /// Defines default output settings. + /// </summary> XmlWriterSettings DefaultWriterSettings { get; } } + /// <summary> + /// XmlInput class represents generic XML input to a trasnformation. The actual + /// XML to be transformed can be provided as string URI, <see cref="Stream"/>, + /// <see cref="TextReader"/>, <see cref="XmlReader"/> or <see cref="IXPathNavigable"/>. + /// Optional <see cref="XmlResolver"/> is used to resolve external references when + /// loading input XML document and URIs in a "document()" function calls during + /// transformation. + /// </summary> public class XmlInput { internal object source ; internal XmlResolver resolver; + + /// <summary> + /// Creates new XmlInput object for an XML document provided as an + /// <see cref="XmlReader"/>. Also registers an <see cref="XmlResolver"/> to be used + /// for resolving external references in the XML document and document() function. + /// </summary> + /// <param name="reader">Input XML document</param> + /// <param name="resolver"><see cref="XmlResolver"/> to resolve external references</param> public XmlInput(XmlReader reader, XmlResolver resolver) { this.source = reader; this.resolver = resolver; } + /// <summary> + /// Creates new XmlInput object for an XML document provided as a + /// <see cref="TextReader"/>. Also registers an <see cref="XmlResolver"/> to be used + /// for resolving external references in the XML document and document() function. + /// </summary> + /// <param name="reader">Input XML document</param> + /// <param name="resolver"><see cref="XmlResolver"/> to resolve external references</param> public XmlInput(TextReader reader, XmlResolver resolver) { this.source = reader; this.resolver = resolver; } + /// <summary> + /// Creates new XmlInput object for an XML document provided as a + /// <see cref="Stream"/>. Also registers an <see cref="XmlResolver"/> to be used + /// for resolving external references in the XML document and document() function. + /// </summary> + /// <param name="stream">Input XML document</param> + /// <param name="resolver"><see cref="XmlResolver"/> to resolve external references</param> public XmlInput(Stream stream, XmlResolver resolver) { this.source = stream; this.resolver = resolver; } + /// <summary> + /// Creates new XmlInput object for an XML document provided as an URI. + /// Also registers an <see cref="XmlResolver"/> to be used + /// for resolving external references in the XML document and document() function. + /// </summary> + /// <param name="uri">Input XML document</param> + /// <param name="resolver"><see cref="XmlResolver"/> to resolve external references</param> public XmlInput(String uri , XmlResolver resolver) { this.source = uri ; this.resolver = resolver; } + /// <summary> + /// Creates new XmlInput object for an XML document provided as an + /// <see cref="IXPathNavigable"/>. Also registers an <see cref="XmlResolver"/> to be used + /// for resolving document() function. + /// </summary> + /// <param name="nav">Input XML document</param> + /// <param name="resolver"><see cref="XmlResolver"/> to resolve external references</param> public XmlInput(IXPathNavigable nav , XmlResolver resolver) { this.source = nav ; this.resolver = resolver; } - public XmlInput(XmlReader reader) : this(reader, new XmlUrlResolver()) {} - public XmlInput(TextReader reader) : this(reader, new XmlUrlResolver()) {} - public XmlInput(Stream stream) : this(stream, new XmlUrlResolver()) {} - public XmlInput(String uri ) : this(uri , new XmlUrlResolver()) {} - public XmlInput(IXPathNavigable nav ) { this.source = nav ; } + /// <summary> + /// Creates new XmlInput object for an XML document provided as an + /// <see cref="XmlReader"/>. + /// </summary> + /// <param name="reader">Input XML document</param> + public XmlInput(XmlReader reader) : this(reader, new DefaultXmlResolver()) {} + /// <summary> + /// Creates new XmlInput object for an XML document provided as a + /// <see cref="TextReader"/>. + /// </summary> + /// <param name="reader">Input XML document</param> + public XmlInput(TextReader reader) : this(reader, new DefaultXmlResolver()) {} + /// <summary> + /// Creates new XmlInput object for an XML document provided as a + /// <see cref="Stream"/>. + /// </summary> + /// <param name="stream">Input XML document</param> + public XmlInput(Stream stream) : this(stream, new DefaultXmlResolver()) {} + /// <summary> + /// Creates new XmlInput object for an XML document provided as an URI. + /// </summary> + /// <param name="uri">Input XML document</param> + public XmlInput(String uri ) : this(uri , new DefaultXmlResolver()) {} + /// <summary> + /// Creates new XmlInput object for an XML document provided as an + /// <see cref="IXPathNavigable"/>. + /// </summary> + /// <param name="nav">Input XML document</param> + public XmlInput(IXPathNavigable nav ) : this(nav , new DefaultXmlResolver()) {} // We can add set of implicit constructors. // I am not shre that this will be for good, so I commented them for now. @@ -35,12 +117,43 @@ //public static implicit operator XmlInput(XPathNavigator nav ) { return new XmlInput(nav ); } // the trick doesn't work with interfaces } + /// <summary> + /// XmlOutput class represents generic XML transformation output. An output XML + /// can be written to an URI, <see cref="Stream"/>, <see cref="TextWriter"/> or + /// <see cref="XmlWriter"/>. + /// </summary> public class XmlOutput { internal object destination; + /// <summary> + /// Creates new XmlOutput object over an <see cref="XmlWriter"/>. + /// </summary> + /// <param name="writer">An <see cref="XmlWriter"/> to write output to</param> public XmlOutput(XmlWriter writer) { this.destination = writer; } + /// <summary> + /// Creates new XmlOutput object over a <see cref="TextWriter"/>. + /// </summary> + /// <param name="writer">A <see cref="TextWriter"/> to write output to</param> public XmlOutput(TextWriter writer) { this.destination = writer; } - public XmlOutput(Stream strm ) { this.destination = strm ; } + /// <summary> + /// Creates new XmlOutput object over a <see cref="Stream"/>. + /// </summary> + /// <param name="stream">A <see cref="Stream"/> to write output to</param> + public XmlOutput(Stream stream ) { this.destination = strm ; } + /// <summary> + /// Creates new XmlOutput object over an URI. + /// </summary> + /// <param name="uri">An URI to write output to</param> public XmlOutput(String uri ) { this.destination = uri ; } // We will add overrides with XmlOutputResolver here later to support multiple output documents (<xsl:result-document>) } + + /// <summary> + /// XmlUrlResolver wrapper allowing us to recognize the case when no + /// XmlResolver was passed. + /// </summary> + internal class DefaultXmlResolver : XmlUrlResolver + { + public DefaultXmlResolver() + : base() {} + } } |