/// <summary> /// Validates the document against the specified XML schema. /// </summary> /// <param name="ctx">Current runtime context.</param> /// <param name="schemaString">The XML schema string.</param> /// <param name="flags">Unsupported.</param> /// <returns><B>True</B> or <B>false</B>.</returns> public virtual bool schemaValidateSource(Context ctx, string schemaString, int flags = 0) { if ((flags & PhpLibXml.LIBXML_SCHEMA_CREATE) == PhpLibXml.LIBXML_SCHEMA_CREATE) { PhpException.Throw(PhpError.Warning, Resources.SchemaCreateUnsupported); } XmlSchema schema; try { schema = XmlSchema.Read(new System.IO.StringReader(schemaString), null); } catch (XmlException e) { PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, e.Message, null); return(false); } XmlDocument.Schemas.Add(schema); try { XmlDocument.Validate(null); } catch (XmlException) { return(false); } finally { XmlDocument.Schemas.Remove(schema); } return(true); }
/// <summary> /// Validates the document against the specified XML schema. /// </summary> /// <param name="ctx">Current runtime context.</param> /// <param name="schemaFile">URL for the file containing the XML schema to load.</param> /// <param name="flags">Unsupported.</param> /// <returns><B>True</B> or <B>false</B>.</returns> public virtual bool schemaValidate(Context ctx, string schemaFile, int flags = 0) { XmlSchema schema; using (PhpStream stream = PhpStream.Open(ctx, schemaFile, "rt")) { if (stream == null) { return(false); } try { schema = XmlSchema.Read(stream.RawStream, null); } catch (XmlException e) { PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, e.Message, schemaFile); return(false); } catch (IOException e) { PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, schemaFile); return(false); } } return(ValidateSchemaInternal(schema, flags)); }
private static bool TryLoadSchema(Context ctx, string url, out XmlSchema schema, out string fullPath) { schema = default; fullPath = default; using var stream = PhpStream.Open(ctx, url, "rt"); if (stream == null) { return(false); } try { schema = XmlSchema.Read(stream.RawStream, null); fullPath = stream.OpenedPath; return(true); } catch (XmlException e) { PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, e.Message, url); return(false); } catch (IOException e) { PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, url); return(false); } }
/// <summary> /// Loads provided XML string into this <see cref="DOMDocument"/>. /// </summary> /// <param name="ctx">Runtime context.</param> /// <param name="source">String representing XML document.</param> /// <param name="options">PHP options.</param> /// <param name="isHtml">Whether the <paramref name="source"/> represents XML generated from HTML document (then it may contain some invalid XML characters).</param> /// <returns></returns> private bool loadXMLInternal(Context ctx, PhpString source, int options, bool isHtml) { this._isHtmlDocument = isHtml; try { var settings = new XmlReaderSettings() { DtdProcessing = DtdProcessing.Parse }; // TODO: options // validating XML reader if (this._validateOnParse) { #pragma warning disable 618 settings.ValidationType = ValidationType.Auto; #pragma warning restore 618 } // do not check invalid characters in HTML (XML) if (isHtml) { settings.CheckCharacters = false; } var reader = source.ContainsBinaryData ? XmlReader.Create(new MemoryStream(source.ToBytes(ctx)), settings) : XmlReader.Create(new StringReader(source.ToString() /*faster*/), settings); // load the document this.XmlDocument.Load(reader); // done return(true); } catch (XmlException e) { PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, e.LineNumber, e.LinePosition, e.Message, null); return(false); } catch (IOException e) { PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, null); return(false); } }
/// <summary> /// Validates the document against the specified XML schema. /// </summary> /// <param name="ctx">Current runtime context.</param> /// <param name="schemaString">The XML schema string.</param> /// <param name="flags">Unsupported.</param> /// <returns><B>True</B> or <B>false</B>.</returns> public virtual bool schemaValidateSource(Context ctx, string schemaString, int flags = 0) { XmlSchema schema; try { schema = XmlSchema.Read(new System.IO.StringReader(schemaString), null); } catch (XmlException e) { PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, e.Message, null); return(false); } return(ValidateSchemaInternal(schema, flags)); }
/// <summary> /// Validates the document against the specified XML schema. /// </summary> /// <param name="ctx">Current runtime context.</param> /// <param name="schemaFile">URL for the file containing the XML schema to load.</param> /// <param name="flags">Unsupported.</param> /// <returns><B>True</B> or <B>false</B>.</returns> public virtual bool schemaValidate(Context ctx, string schemaFile, int flags = 0) { if ((flags & PhpLibXml.LIBXML_SCHEMA_CREATE) == PhpLibXml.LIBXML_SCHEMA_CREATE) { PhpException.Throw(PhpError.Warning, Resources.SchemaCreateUnsupported); } XmlSchema schema; using (PhpStream stream = PhpStream.Open(ctx, schemaFile, "rt")) { if (stream == null) { return(false); } try { schema = XmlSchema.Read(stream.RawStream, null); } catch (XmlException e) { PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, e.Message, schemaFile); return(false); } catch (IOException e) { PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, schemaFile); return(false); } } XmlDocument.Schemas.Add(schema); try { XmlDocument.Validate(null); } catch (XmlException) { return(false); } finally { XmlDocument.Schemas.Remove(schema); } return(true); }
/// <summary> /// Loads the XML document from the specified URL. /// </summary> /// <param name="ctx">Current runtime context.</param> /// <param name="filename">URL for the file containing the XML document to load.</param> /// <param name="options">Undocumented.</param> /// <returns><b>True</b> on success or <b>false</b> on failure.</returns> public virtual bool load(Context ctx, string filename, int options = 0) { // TODO: this method can be called both statically and via an instance _isHtmlDocument = false; using (PhpStream stream = PhpStream.Open(ctx, filename, "rt")) { if (stream == null) { return(false); } try { var settings = new XmlReaderSettings() { DtdProcessing = DtdProcessing.Parse }; // TODO: options // validating XML reader if (this._validateOnParse) { #pragma warning disable 618 settings.ValidationType = ValidationType.Auto; #pragma warning restore 618 } XmlDocument.Load(XmlReader.Create(stream.RawStream, settings, XIncludeHelper.UriResolver(filename, ctx.WorkingDirectory))); } catch (XmlException e) { PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, filename); return(false); } catch (IOException e) { PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, filename); return(false); } } return(true); }
/// <summary> /// Loads provided XML string into this <see cref="DOMDocument"/>. /// </summary> /// <param name="ctx">Runtime context.</param> /// <param name="xmlString">String representing XML document.</param> /// <param name="options">PHP options.</param> /// <param name="isHtml">Whether the <paramref name="xmlString"/> represents XML generated from HTML document (then it may contain some invalid XML characters).</param> /// <returns></returns> private bool loadXMLInternal(Context ctx, string xmlString, int options, bool isHtml) { this._isHtmlDocument = isHtml; var stream = new StringReader(xmlString); try { XmlReaderSettings settings = new XmlReaderSettings() { DtdProcessing = DtdProcessing.Ignore }; // validating XML reader if (this._validateOnParse) { // TODO: Enable when DtdProcessing.Parse is enabled in System.Xml.ReaderWriter package //#pragma warning disable 618 //settings.DtdProcessing = DtdProcessing.Parse; //#pragma warning restore 618 } // do not check invalid characters in HTML (XML) if (isHtml) { settings.CheckCharacters = false; } // load the document this.XmlDocument.Load(XmlReader.Create(stream, settings)); // done return(true); } catch (XmlException e) { PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, e.LineNumber, e.LinePosition, e.Message, null); return(false); } catch (IOException e) { PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, null); return(false); } }
/// <summary> /// Processes HTML errors, if any. /// </summary> /// <param name="ctx">Runtime context.</param> /// <param name="htmlDoc"><see cref="HtmlAgilityPack.HtmlDocument"/> instance to process errors from.</param> /// <param name="filename">HTML file name or <c>null</c> if HTML has been loaded from a string.</param> private void CheckHtmlErrors(Context ctx, HtmlAgilityPack.HtmlDocument htmlDoc, string filename) { Debug.Assert(htmlDoc != null); foreach (var error in htmlDoc.ParseErrors) { switch (error.Code) { case HtmlAgilityPack.HtmlParseErrorCode.EndTagNotRequired: case HtmlAgilityPack.HtmlParseErrorCode.TagNotOpened: break; default: PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, error.Line, error.LinePosition, "(" + error.Code.ToString() + ")" + error.Reason, filename); break; } } }
/// <summary> /// Saves the XML document to the specified stream. /// </summary> /// <param name="ctx">Current runtime context.</param> /// <param name="fileName">The location of the file where the document should be saved.</param> /// <param name="options">Unsupported.</param> /// <returns>The number of bytes written or <B>false</B> on error.</returns> public virtual PhpValue save(Context ctx, string fileName, int options = 0) { using (PhpStream stream = PhpStream.Open(ctx, fileName, "wt")) { if (stream == null) { return(PhpValue.Create(false)); } try { // direct stream write indents if (_formatOutput) { XmlDocument.Save(stream.RawStream); } else { var settings = new XmlWriterSettings() { Encoding = Utils.GetNodeEncoding(ctx, XmlNode) }; using (var writer = System.Xml.XmlWriter.Create(stream.RawStream, settings)) { XmlDocument.Save(writer); } } } catch (XmlException e) { PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, fileName); return(PhpValue.False); } catch (IOException e) { PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, fileName); return(PhpValue.False); } // TODO: return(PhpValue.Create(stream.RawStream.CanSeek ? stream.RawStream.Position : 1)); } }
/// <summary> /// Loads the XML document from the specified URL. /// </summary> /// <param name="ctx">Current runtime context.</param> /// <param name="fileName">URL for the file containing the XML document to load.</param> /// <param name="options">Undocumented.</param> /// <returns><b>True</b> on success or <b>false</b> on failure.</returns> public virtual bool load(Context ctx, string fileName, int options = 0) { // TODO: this method can be called both statically and via an instance _isHtmlDocument = false; using (PhpStream stream = PhpStream.Open(ctx, fileName, "rt")) { if (stream == null) { return(false); } try { if (_validateOnParse) { // create a validating XML reader XmlReaderSettings settings = new XmlReaderSettings(); //#pragma warning disable 618 // settings.ValidationType = ValidationType.Auto; //#pragma warning restore 618 XmlDocument.Load(XmlReader.Create(stream.RawStream, settings)); } else { XmlDocument.Load(stream.RawStream); } } catch (XmlException e) { PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, fileName); return(false); } catch (IOException e) { PhpLibXml.IssueXmlError(ctx, PhpLibXml.LIBXML_ERR_ERROR, 0, 0, 0, e.Message, fileName); return(false); } } return(true); }
/// <summary> /// Treats all include tags, if there are bad reference on document, catches exception and tries to find fallback, which is treated as document. /// </summary> /// <param name="includeNodes">Nodes, which will be replace</param> /// <param name="document">Document, which contains includeNodes</param> /// <param name="absoluteUri">Uri of document</param> /// <param name="nsPrefix">Prefix of include namespace</param> /// <param name="nsm">Namespace Manager of document</param> /// <returns></returns> bool TreatIncludes(XmlElement[] includeNodes, XmlDocument document, string absoluteUri, string nsPrefix, XmlNamespaceManager nsm) { foreach (var includeElement in includeNodes) { var valueOfXPoiner = includeElement.GetAttribute(atXPointer); var valueOfHref = includeElement.GetAttribute(atHref); if (string.IsNullOrEmpty(valueOfHref)) // There must be xpointer Attribute, if not, fatal error.. { if (string.IsNullOrEmpty(valueOfXPoiner)) { PhpLibXml.IssueXmlError(_ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, $"DOMDocument::xinclude(): detected a local recursion with no xpointer in {absoluteUri} in {_ctx.MainScriptFile.Path}", absoluteUri); return(true); } _documents.Push(document); var includeUri = includeElement.BaseURI + valueOfXPoiner; if (_references.ContainsKey(includeUri)) // fatal error, cycle recursion { PhpLibXml.IssueXmlError(_ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, $"DOMDocument::xinclude(): detected a recursion in {absoluteUri} in {_ctx.MainScriptFile.Path}", absoluteUri); return(true); } _references[absoluteUri] = includeUri; IncludeXml(includeElement.BaseURI, includeElement, null, valueOfXPoiner); return(false); } // Resolving absolute and relative uri... string uri = UriResolver(valueOfHref, Path.GetDirectoryName(absoluteUri)); // Resolving type of parsing. string typeOfParse = includeElement.GetAttribute(atParse); try { if (string.Equals(typeOfParse, "text", StringComparison.OrdinalIgnoreCase)) { _documents.Push(document); IncludeText(uri, includeElement); } else { if (_references.ContainsKey(uri + valueOfXPoiner)) // fatal error, cycle recursion { PhpLibXml.IssueXmlError(_ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, $"DOMDocument::xinclude(): detected a recursion in {absoluteUri} in {_ctx.MainScriptFile.Path}", absoluteUri); //return true; } else { _documents.Push(document); _references[absoluteUri] = uri + valueOfXPoiner; IncludeXml(uri, includeElement, null, string.IsNullOrEmpty(valueOfXPoiner) ? null : valueOfXPoiner); } } } catch (System.IO.FileNotFoundException) { PhpLibXml.IssueXmlError(_ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, $"DOMDocument::xinclude(): I/O warning : failed to load external entity "{absoluteUri}" in {_ctx.MainScriptFile.Path}", absoluteUri); _documents.Pop(); XmlElement[] fallbacks = includeElement.GetElementsByTagName(nsPrefix + ":" + etFallback).OfType <XmlElement>().ToArray <XmlElement>(); if (fallbacks.Length > 1) // fatal error { PhpLibXml.IssueXmlError(_ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, $"DOMDocument::xinclude(): include has multiple fallback children in {_ctx.MainScriptFile.Path}", _ctx.MainScriptFile.Path); return(true); } if (fallbacks.Length == 1) { XmlElement[] includes = fallbacks[0].SelectNodes($".//{nsPrefix}:{etInclude}[ not( descendant::{nsPrefix}:{etFallback} ) ]", nsm).OfType <XmlElement>().ToArray(); while (fallbacks[0].ChildNodes.Count != 0) { includeElement.ParentNode.InsertAfter(fallbacks[0].LastChild, includeElement); } TreatIncludes(includes, document, absoluteUri, nsPrefix, nsm); includeElement.ParentNode.RemoveChild(includeElement); } else // error missing fallback { PhpLibXml.IssueXmlError(_ctx, PhpLibXml.LIBXML_ERR_WARNING, 0, 0, 0, $"DOMDocument::xinclude(): could not load {absoluteUri}, and no fallback was found in {_ctx.MainScriptFile.Path}", absoluteUri); return(true); } } _references = new Dictionary <string, string>(); } return(false); }