// Check the "HasNamespace" method. public void TestXmlNamespaceManagerHas() { NameTable table = new NameTable(); XmlNamespaceManager ns = new XmlNamespaceManager(table); Assert("Has (1)", ns.HasNamespace("xml")); Assert("Has (2)", ns.HasNamespace("xmlns")); Assert("Has (3)", ns.HasNamespace("")); Assert("Has (4)", !ns.HasNamespace("foo")); ns.AddNamespace("foo", "uri"); Assert("Has (5)", ns.HasNamespace("xml")); Assert("Has (6)", ns.HasNamespace("xmlns")); Assert("Has (7)", ns.HasNamespace("")); Assert("Has (8)", ns.HasNamespace("foo")); ns.PushScope(); ns.AddNamespace("bar", "uri2"); Assert("Has (9)", ns.HasNamespace("xml")); Assert("Has (10)", ns.HasNamespace("xmlns")); Assert("Has (11)", ns.HasNamespace("")); Assert("Has (12)", ns.HasNamespace("foo")); Assert("Has (13)", ns.HasNamespace("bar")); ns.PopScope(); Assert("Has (14)", ns.HasNamespace("xml")); Assert("Has (15)", ns.HasNamespace("xmlns")); Assert("Has (16)", ns.HasNamespace("")); Assert("Has (17)", ns.HasNamespace("foo")); Assert("Has (18)", !ns.HasNamespace("bar")); ns.RemoveNamespace("foo", "uri"); Assert("Has (19)", ns.HasNamespace("xml")); Assert("Has (20)", ns.HasNamespace("xmlns")); Assert("Has (21)", ns.HasNamespace("")); Assert("Has (22)", !ns.HasNamespace("foo")); Assert("Has (23)", !ns.HasNamespace("bar")); ns.RemoveNamespace("", ""); Assert("Has (24)", ns.HasNamespace("xml")); Assert("Has (25)", ns.HasNamespace("xmlns")); Assert("Has (26)", ns.HasNamespace("")); Assert("Has (27)", !ns.HasNamespace("foo")); Assert("Has (28)", !ns.HasNamespace("bar")); Assert("Has (29)", !ns.HasNamespace(null)); }
private bool ExecuteCore(string filename) { XmlDocument = new XmlDocument(); Modified = false; try { if (!string.IsNullOrEmpty(filename) && System.IO.File.Exists(filename)) { // load the file try { XmlDocument.Load(filename); } catch (XmlException ex) { Log.LogError("Invalid XML near line {0}, position {1}", ex.LineNumber, ex.LinePosition); return(false); } } else if (!AllowEmptyDocument) { // if empty documents are not allowed, error out now Log.LogError("File not found: {0}", File); return(false); } XPathNamespaceManager = new XmlNamespaceManager(XmlDocument.NameTable); if (!string.IsNullOrEmpty(XPathNamespaces)) { foreach (var declaration in XPathNamespaces.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) { var index = declaration.IndexOf('='); if (index < 0) { Log.LogError("XML namespace declarations should be formatted as a semicolon-delimited list of PREFIX=URI entries"); return(false); } var prefix = declaration.Substring(0, index); var uri = declaration.Substring(index + 1); if (XPathNamespaceManager.HasNamespace(prefix)) { Log.LogError("Duplicate declaration for XML namespace prefix {0}", prefix); return(false); } XPathNamespaceManager.AddNamespace(prefix, uri); } } // perform the task var result = PerformTask(); if (result && Modified) { // save output if task was successful and changes were made if (!string.IsNullOrEmpty(filename)) { XmlDocument.Save(filename); } } return(result); } #if !DEBUG catch (Exception ex) { Log.LogErrorFromException(ex); return(false); } #endif finally { XPathNamespaceManager = null; XmlDocument = null; Modified = false; } }
/// <inheritdoc /> public override void Apply(XmlDocument document, string key) { XmlElement html = document.DocumentElement; XmlNode head = html.SelectSingleNode(Help2XPath.Head); if (head == null) { head = document.CreateElement(Help2XPath.Head); if (!html.HasChildNodes) { html.AppendChild(head); } else { html.InsertBefore(head, html.FirstChild); } } else { // !EFW - Remove the unnecessary Help 2 CSS link element from the header XmlNode hxLink = head.SelectSingleNode(Help2XPath.HxLink); if (hxLink != null) { head.RemoveChild(hxLink); } } // Apply some fix-ups if not branding aware if (head.SelectSingleNode("meta[@name='BrandingAware']") == null) { ModifyAttribute(document, "id", "mainSection"); ModifyAttribute(document, "class", "members"); } AddMHSMeta(head, MHSMetaName.SelfBranded, _selfBranded.ToString().ToLowerInvariant()); AddMHSMeta(head, MHSMetaName.TopicVersion, _topicVersion); string locale = _locale; string id = Guid.NewGuid().ToString(); XmlNode xml = head.SelectSingleNode(Help2XPath.Xml); if (xml != null) { XmlNamespaceManager nsmgr = new XmlNamespaceManager(document.NameTable); if (!nsmgr.HasNamespace(Help2Namespace.Prefix)) { nsmgr.AddNamespace(Help2Namespace.Prefix, Help2Namespace.Uri); } XmlElement elem = xml.SelectSingleNode(Help2XPath.TocTitle, nsmgr) as XmlElement; if (elem != null) { AddMHSMeta(head, MHSMetaName.Title, elem.GetAttribute(Help2Attr.Title)); } foreach (XmlElement keyword in xml.SelectNodes(String.Format(CultureInfo.InvariantCulture, Help2XPath.Keyword, Help2Value.K), nsmgr)) { AddMHSMeta(head, MHSMetaName.Keywords, keyword.GetAttribute(Help2Attr.Term), true); } foreach (XmlElement keyword in xml.SelectNodes(String.Format(CultureInfo.InvariantCulture, Help2XPath.Keyword, Help2Value.F), nsmgr)) { AddMHSMeta(head, MHSMetaName.F1, keyword.GetAttribute(Help2Attr.Term), true); } foreach (XmlElement lang in xml.SelectNodes(String.Format(CultureInfo.InvariantCulture, Help2XPath.Attr, Help2Value.DevLang), nsmgr)) { AddMHSMeta(head, MHSMetaName.Category, Help2Value.DevLang + ":" + lang.GetAttribute(Help2Attr.Value), true); } elem = xml.SelectSingleNode(String.Format(CultureInfo.InvariantCulture, Help2XPath.Attr, Help2Value.Abstract), nsmgr) as XmlElement; if (elem != null) { AddMHSMeta(head, MHSMetaName.Description, elem.GetAttribute(Help2Attr.Value)); } elem = xml.SelectSingleNode(String.Format(CultureInfo.InvariantCulture, Help2XPath.Attr, Help2Value.AssetID), nsmgr) as XmlElement; if (elem != null) { id = elem.GetAttribute(Help2Attr.Value); } if (String.IsNullOrEmpty(locale)) { elem = xml.SelectSingleNode(String.Format(CultureInfo.InvariantCulture, Help2XPath.Attr, Help2Value.Locale), nsmgr) as XmlElement; if (elem != null) { locale = elem.GetAttribute(Help2Attr.Value); } } // !EFW - Remove the XML data island as it serves no purpose head.RemoveChild(xml); } if (String.IsNullOrEmpty(locale)) { locale = MHSDefault.Locale; } AddMHSMeta(head, MHSMetaName.Locale, locale); AddMHSMeta(head, MHSMetaName.TopicLocale, locale); AddMHSMeta(head, MHSMetaName.Id, id); TocInfo tocInfo; if (_toc.TryGetValue(id, out tocInfo)) { AddMHSMeta(head, MHSMetaName.TocParent, tocInfo.Parent); if (tocInfo.Parent != MHSDefault.TocParent) { AddMHSMeta(head, MHSMetaName.TocParentVersion, tocInfo.ParentVersion); } AddMHSMeta(head, MHSMetaName.TocOrder, tocInfo.Order.ToString(CultureInfo.InvariantCulture)); } }
public IEnumerable <DataListItem> GetItems(Dictionary <string, object> config) { var items = new List <DataListItem>(); var url = config.GetValueAs("url", string.Empty); if (string.IsNullOrWhiteSpace(url)) { return(items); } var path = url.InvariantStartsWith("http") == false ? IOHelper.MapPath(url) : url; var doc = default(XPathDocument); try { doc = new XPathDocument(path); } catch (WebException ex) { _logger.Error <XmlDataListSource>(ex, $"Unable to retrieve data from '{path}'."); return(items); } catch (XmlException ex) { _logger.Error <XmlDataListSource>(ex, "Unable to load XML data."); } if (doc == null) { return(items); } var itemsXPath = config.GetValueAs("itemsXPath", string.Empty); if (string.IsNullOrWhiteSpace(itemsXPath)) { return(items); } var nav = doc.CreateNavigator(); var namespaces = nav.Select("//namespace::*"); var nsmgr = new XmlNamespaceManager(nav.NameTable); var idx = 0; foreach (XPathNavigator ns in namespaces) { var prefix = nsmgr.LookupPrefix(ns.Value); if (nsmgr.HasNamespace(prefix) == false) { nsmgr.AddNamespace(string.IsNullOrWhiteSpace(ns.Name) == false ? ns.Name : $"ns{++idx}", ns.Value); } } var nodes = nav.Select(itemsXPath, nsmgr); if (nodes.Count == 0) { _logger.Warn <XmlDataListSource>($"The XPath '{itemsXPath}' did not match any items in the XML: {nav.OuterXml.Substring(0, Math.Min(300, nav.OuterXml.Length))}"); return(items); } var nameXPath = config.GetValueAs("nameXPath", "text()"); var valueXPath = config.GetValueAs("valueXPath", "text()"); var iconXPath = config.GetValueAs("iconXPath", string.Empty); var descriptionXPath = config.GetValueAs("descriptionXPath", string.Empty); foreach (XPathNavigator node in nodes) { var name = node.SelectSingleNode(nameXPath, nsmgr); var value = node.SelectSingleNode(valueXPath, nsmgr); if (name != null && value != null) { var icon = string.IsNullOrWhiteSpace(iconXPath) == false ? node.SelectSingleNode(iconXPath, nsmgr) : null; var description = string.IsNullOrWhiteSpace(descriptionXPath) == false ? node.SelectSingleNode(descriptionXPath, nsmgr) : null; items.Add(new DataListItem { Icon = icon?.Value, Name = name.Value, Description = description?.Value, Value = value.Value }); } else { var outerXml = node.OuterXml.Substring(0, Math.Min(300, node.OuterXml.Length)); if (name == null) { _logger.Warn <XmlDataListSource>($"The XPath '{nameXPath}' did not match a 'name' in the item XML: {outerXml}"); } if (value == null) { _logger.Warn <XmlDataListSource>($"The XPath '{valueXPath}' did not match a 'value' in the item XML: {outerXml}"); } } } return(items); }
/// <summary> /// Determine whether an ElementCtor, AttributeCtor, or NamespaceDecl's namespace is already declared. If it is, /// set the IsNamespaceInScope property to True. Otherwise, add the namespace to the set of in-scope namespaces if /// addInScopeNmsp is True. Return false if the name is computed or is invalid. /// </summary> private bool CheckNamespaceInScope(QilBinary nd) { QilName ndName; string prefix, ns, prefixExisting, nsExisting; XPathNodeType nodeType; switch (nd.NodeType) { case QilNodeType.ElementCtor: case QilNodeType.AttributeCtor: ndName = nd.Left as QilName; if (ndName != null) { prefix = ndName.Prefix; ns = ndName.NamespaceUri; nodeType = (nd.NodeType == QilNodeType.ElementCtor) ? XPathNodeType.Element : XPathNodeType.Attribute; break; } // Not a literal name, so return false return(false); default: Debug.Assert(nd.NodeType == QilNodeType.NamespaceDecl); prefix = (string)(QilLiteral)nd.Left; ns = (string)(QilLiteral)nd.Right; nodeType = XPathNodeType.Namespace; break; } // Attribute with null namespace and xmlns:xml are always in-scope if (nd.NodeType == QilNodeType.AttributeCtor && ns.Length == 0 || prefix == "xml" && ns == XmlReservedNs.NsXml) { XmlILConstructInfo.Write(nd).IsNamespaceInScope = true; return(true); } // Don't process names that are invalid if (!ValidateNames.ValidateName(prefix, string.Empty, ns, nodeType, ValidateNames.Flags.CheckPrefixMapping)) { return(false); } // Atomize names prefix = _nsmgr.NameTable.Add(prefix); ns = _nsmgr.NameTable.Add(ns); // Determine whether namespace is already in-scope for (int iNmsp = 0; iNmsp < _cntNmsp; iNmsp++) { _nsmgr.GetNamespaceDeclaration(iNmsp, out prefixExisting, out nsExisting); // If prefix is already declared, if ((object)prefix == (object)prefixExisting) { // Then if the namespace is the same, this namespace is redundant if ((object)ns == (object)nsExisting) { XmlILConstructInfo.Write(nd).IsNamespaceInScope = true; } // Else quit searching, because any further matching prefixes will be hidden (not in-scope) Debug.Assert(nd.NodeType != QilNodeType.NamespaceDecl || !_nsmgr.HasNamespace(prefix) || _nsmgr.LookupNamespace(prefix) == ns, "Compilers must ensure that namespace declarations do not conflict with the namespace used by the element constructor."); break; } } // If not in-scope, then add if it's allowed if (_addInScopeNmsp) { _nsmgr.AddNamespace(prefix, ns); _cntNmsp++; } return(true); }
public EpisodeInfo GetEpisodeInfo(string progExtId, ProgrammeInfo progInfo, string episodeExtId) { XmlDocument rss = this.LoadFeedXml(new Uri(progExtId)); XmlNamespaceManager namespaceMgr = this.CreateNamespaceMgr(rss); XmlNode itemNode = this.ItemNodeFromEpisodeID(rss, episodeExtId); if (itemNode == null) { return(null); } XmlNode titleNode = itemNode.SelectSingleNode("./title"); XmlNode pubDateNode = itemNode.SelectSingleNode("./pubDate"); XmlNode enclosureNode = itemNode.SelectSingleNode("./enclosure"); if (enclosureNode == null) { return(null); } XmlAttribute urlAttrib = enclosureNode.Attributes["url"]; if (urlAttrib == null) { return(null); } try { new Uri(urlAttrib.Value); } catch (UriFormatException) { // The enclosure url is empty or malformed return(null); } EpisodeInfo episodeInfo = new EpisodeInfo(); if (titleNode == null || string.IsNullOrEmpty(titleNode.InnerText)) { return(null); } episodeInfo.Name = titleNode.InnerText; XmlNode descriptionNode = null; // If the item has an itunes:summary tag use this for the description (as it shouldn't contain HTML) if (namespaceMgr.HasNamespace("itunes")) { descriptionNode = itemNode.SelectSingleNode("./itunes:summary", namespaceMgr); } if (descriptionNode != null && !string.IsNullOrEmpty(descriptionNode.InnerText)) { episodeInfo.Description = descriptionNode.InnerText; } else { // Fall back to the standard description tag, but strip the HTML descriptionNode = itemNode.SelectSingleNode("./description"); if (descriptionNode != null && !string.IsNullOrEmpty(descriptionNode.InnerText)) { episodeInfo.Description = HtmlToText.ConvertHtml(descriptionNode.InnerText); } } try { XmlNode durationNode = itemNode.SelectSingleNode("./itunes:duration", namespaceMgr); if (durationNode != null) { string[] splitDuration = durationNode.InnerText.Split(new char[] { '.', ':' }); if (splitDuration.GetUpperBound(0) == 0) { episodeInfo.Duration = Convert.ToInt32(splitDuration[0], CultureInfo.InvariantCulture); } else if (splitDuration.GetUpperBound(0) == 1) { episodeInfo.Duration = (Convert.ToInt32(splitDuration[0], CultureInfo.InvariantCulture) * 60) + Convert.ToInt32(splitDuration[1], CultureInfo.InvariantCulture); } else { episodeInfo.Duration = (((Convert.ToInt32(splitDuration[0], CultureInfo.InvariantCulture) * 60) + Convert.ToInt32(splitDuration[1], CultureInfo.InvariantCulture)) * 60) + Convert.ToInt32(splitDuration[2], CultureInfo.InvariantCulture); } } else { episodeInfo.Duration = null; } } catch { episodeInfo.Duration = null; } if (pubDateNode != null) { string pubDate = pubDateNode.InnerText.Trim(); int zonePos = pubDate.LastIndexOf(" ", StringComparison.Ordinal); TimeSpan offset = new TimeSpan(0); if (zonePos > 0) { string zone = pubDate.Substring(zonePos + 1); string zoneFree = pubDate.Substring(0, zonePos); switch (zone) { case "GMT": // No need to do anything break; case "UT": offset = new TimeSpan(0); pubDate = zoneFree; break; case "EDT": offset = new TimeSpan(-4, 0, 0); pubDate = zoneFree; break; case "EST": case "CDT": offset = new TimeSpan(-5, 0, 0); pubDate = zoneFree; break; case "CST": case "MDT": offset = new TimeSpan(-6, 0, 0); pubDate = zoneFree; break; case "MST": case "PDT": offset = new TimeSpan(-7, 0, 0); pubDate = zoneFree; break; case "PST": offset = new TimeSpan(-8, 0, 0); pubDate = zoneFree; break; default: if (zone.Length >= 4 && (Information.IsNumeric(zone) || Information.IsNumeric(zone.Substring(1)))) { try { int value = int.Parse(zone, NumberStyles.AllowLeadingSign, CultureInfo.InvariantCulture); offset = new TimeSpan(value / 100, value % 100, 0); pubDate = zoneFree; } catch (FormatException) { // The last part of the date was not a time offset } } break; } } // Strip the day of the week from the beginning of the date string if it is there, // as it can contradict the date itself. string[] days = { "mon,", "tue,", "wed,", "thu,", "fri,", "sat,", "sun," }; foreach (string day in days) { if (pubDate.StartsWith(day, StringComparison.OrdinalIgnoreCase)) { pubDate = pubDate.Substring(day.Length).Trim(); break; } } try { episodeInfo.Date = DateTime.Parse(pubDate, null, DateTimeStyles.AssumeUniversal); episodeInfo.Date = episodeInfo.Date.Value.Subtract(offset); } catch (FormatException) { episodeInfo.Date = null; } } else { episodeInfo.Date = null; } episodeInfo.Image = this.RSSNodeImage(itemNode, namespaceMgr); return(episodeInfo); }