// // XslOutput.cs // // Authors: // Ben Maurer (bmaurer@users.sourceforge.net) // Atsushi Enomoto (ginga@kit.hi-ho.ne.jp) // Oleg Tkachenko (oleg@tkachenko.com) // // (C) 2003 Ben Maurer // (C) 2003 Atsushi Enomoto // (C) 2003 Oleg Tkachenko // // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // using System; using System.Collections; using System.Xml; using System.Xml.Schema; using System.Xml.XPath; using System.Xml.Xsl; using System.Text; namespace Mono.Xml.Xsl { using QName = System.Xml.XmlQualifiedName; internal enum OutputMethod { XML, HTML, Text, Custom, Unknown } internal enum StandaloneType { NONE, YES, NO } internal class XslOutput // also usable for xsl:result-document { string uri; QName customMethod; OutputMethod method = OutputMethod.Unknown; string version; Encoding encoding = System.Text.Encoding.UTF8; bool omitXmlDeclaration; StandaloneType standalone = StandaloneType.NONE; string doctypePublic; string doctypeSystem; QName [] cdataSectionElements; string indent; string mediaType; string stylesheetVersion; // for compilation only. ArrayList cdSectsList = new ArrayList (); public XslOutput (string uri, string stylesheetVersion) { this.uri = uri; this.stylesheetVersion = stylesheetVersion; } public OutputMethod Method { get { return method; }} public QName CustomMethod { get { return customMethod; }} public string Version { get { return version; } } public Encoding Encoding { get { return encoding; } } public string Uri { get { return uri; } } public bool OmitXmlDeclaration { get { return omitXmlDeclaration; } } public StandaloneType Standalone { get { return standalone; } } public string DoctypePublic { get { return doctypePublic; } } public string DoctypeSystem { get { return doctypeSystem; } } public QName [] CDataSectionElements { get { if (cdataSectionElements == null) cdataSectionElements = cdSectsList.ToArray (typeof (QName)) as QName []; return cdataSectionElements; } } public string Indent { get { return indent; } } public string MediaType { get { return mediaType; } } public void Fill (XPathNavigator nav) { if (nav.MoveToFirstAttribute ()) { ProcessAttribute (nav); while (nav.MoveToNextAttribute ()) { ProcessAttribute (nav); } // move back to original position nav.MoveToParent (); } } private void ProcessAttribute (XPathNavigator nav) { // skip attributes from non-default namespace if (nav.NamespaceURI != string.Empty) { return; } string value = nav.Value; switch (nav.LocalName) { case "cdata-section-elements": if (value.Length > 0) { cdSectsList.AddRange (XslNameUtil.FromListString (value, nav)); } break; case "method": if (value.Length == 0) { break; } switch (value) { case "xml": method = OutputMethod.XML; break; case "html": omitXmlDeclaration = true; method = OutputMethod.HTML; break; case "text": omitXmlDeclaration = true; method = OutputMethod.Text; break; default: method = OutputMethod.Custom; customMethod = XslNameUtil.FromString (value, nav); if (customMethod.Namespace == String.Empty) { IXmlLineInfo li = nav as IXmlLineInfo; throw new XsltCompileException (new ArgumentException ( "Invalid output method value: '" + value + "'. It" + " must be either 'xml' or 'html' or 'text' or QName."), nav.BaseURI, li != null ? li.LineNumber : 0, li != null ? li.LinePosition : 0); } break; } break; case "version": if (value.Length > 0) { this.version = value; } break; case "encoding": if (value.Length > 0) { try { this.encoding = System.Text.Encoding.GetEncoding (value); } catch (ArgumentException) { // MS.NET just leaves the default encoding when encoding is unknown } catch (NotSupportedException) { // Workaround for a bug in System.Text, it throws invalid exception } } break; case "standalone": switch (value) { case "yes": this.standalone = StandaloneType.YES; break; case "no": this.standalone = StandaloneType.NO; break; default: if (stylesheetVersion != "1.0") break; IXmlLineInfo li = nav as IXmlLineInfo; throw new XsltCompileException (new XsltException ( "'" + value + "' is an invalid value for 'standalone'" + " attribute.", (Exception) null), nav.BaseURI, li != null ? li.LineNumber : 0, li != null ? li.LinePosition : 0); } break; case "doctype-public": this.doctypePublic = value; break; case "doctype-system": this.doctypeSystem = value; break; case "media-type": if (value.Length > 0) { this.mediaType = value; } break; case "omit-xml-declaration": switch (value) { case "yes": this.omitXmlDeclaration = true; break; case "no": this.omitXmlDeclaration = false; break; default: if (stylesheetVersion != "1.0") break; IXmlLineInfo li = nav as IXmlLineInfo; throw new XsltCompileException (new XsltException ( "'" + value + "' is an invalid value for 'omit-xml-declaration'" + " attribute.", (Exception) null), nav.BaseURI, li != null ? li.LineNumber : 0, li != null ? li.LinePosition : 0); } break; case "indent": indent = value; if (stylesheetVersion != "1.0") break; switch (value) { case "yes": case "no": break; default: switch (method) { case OutputMethod.Custom: break; default: throw new XsltCompileException (String.Format ("Unexpected 'indent' attribute value in 'output' element: '{0}'", value), null, nav); } break; } break; default: if (stylesheetVersion != "1.0") break; IXmlLineInfo xli = nav as IXmlLineInfo; throw new XsltCompileException (new XsltException ( "'" + nav.LocalName + "' is an invalid attribute for 'output'" + " element.", (Exception) null), nav.BaseURI, xli != null ? xli.LineNumber : 0, xli != null ? xli.LinePosition : 0); } } } }