private void ParseRssTag(XmlAttributeCollection xmlAttributes) { if (xmlAttributes != null) { foreach (XmlAttribute itemNode in xmlAttributes) { switch (itemNode.Name.ToLower()) { case "version": switch (itemNode.InnerText) { case "0.91": rssVersion = RssVersion.RSS091; break; case "0.92": rssVersion = RssVersion.RSS092; break; case "2.0": rssVersion = RssVersion.RSS20; break; default: rssVersion = RssVersion.NotSupported; break; } break; } } } }
/// <summary> /// Save the RSS object with specified version number to XML. /// </summary> /// <param name="version"></param> /// <param name="encoding"></param> /// <param name="version"></param> /// <returns></returns> public XmlDocument Save(RssVersion version, string encoding, string customVersion) { if (customVersion == null) { throw new ArgumentNullException("customVersion"); } if (version == RssVersion.RSS_0_91) { if (ValidateOnSave) { Validate(version, this.ValidateContent); } return(SerializeToXml_0_91(encoding, customVersion)); } else if (version == RssVersion.RSS_0_92) { if (ValidateOnSave) { Validate(version, this.ValidateContent); } return(SerializeToXml_0_92(encoding, customVersion)); } else if (version == RssVersion.RSS_2_0_1) { if (ValidateOnSave) { Validate(version, this.ValidateContent); } return(SerializeToXml_2_0_1(encoding, customVersion)); } throw new ArgumentException(Rss.RSS_ERRORMESSAGE_UNKNOWN_VALUE, RSS_ATTRIBUTE_VERSION); }
/// <summary> /// /// </summary> /// <param name="version"></param> private void ValidateProtocol(RssVersion version) { if (this.Protocol == null) { return; } if (version == RssVersion.RSS_0_92) { string protocol = this.Protocol; foreach (string validProtocol in Rss.RSS_VALIDVALUES_CLOUD_PROTOCOL_0_92) { if (protocol == validProtocol) { return; } } string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_FAILED, RSS_ELEMENT_CLOUD, RSS_ELEMENT_PROTOCOL); throw new SyndicationValidationException(msg); } else if (version == RssVersion.RSS_2_0_1) { string protocol = this.Protocol; foreach (string validProtocol in Rss.RSS_VALIDVALUES_CLOUD_PROTOCOL_2_0_1) { if (protocol == validProtocol) { return; } } string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_FAILED, RSS_ELEMENT_CLOUD, RSS_ELEMENT_PROTOCOL); throw new SyndicationValidationException(msg); } }
/// <summary> /// /// </summary> /// <param name="version"></param> /// <param name="validateContent"></param> public void Validate(RssVersion version, bool validateContent) { bool bHit = false; if (version == RssVersion.RSS_0_91) { Validate_0_91(validateContent); bHit = true; } else if (version == RssVersion.RSS_0_92) { Validate_0_92(validateContent); bHit = true; } else if (version == RssVersion.RSS_2_0_1) { Validate_2_0_1(validateContent); bHit = true; } if (!bHit) { throw new SyndicationValidationException(Rss.RSS_ERRORMESSAGE_CANNOT_VALIDATE_UNRECOGNIZED_VERSION); } }
/// <summary> /// /// </summary> /// <param name="version"></param> private void ValidateUrl(RssVersion version) { if (this.URL == null) { return; } if (version == RssVersion.RSS_0_92) { string url = this.URL.ToLower().Trim(); foreach (string validPrefix in Rss.RSS_VALIDVALUES_LINK_URL_0_92) { if (url.StartsWith(validPrefix)) { return; } } string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_LINK_URL_WRONG_TYPE_0_92, RSS_ELEMENT_URL, this.URL); throw new SyndicationValidationException(msg); } else if (version == RssVersion.RSS_2_0_1) { string url = this.URL.ToLower().Trim(); foreach (string validPrefix in Rss.RSS_VALIDVALUES_LINK_URL_2_0_1) { if (url.StartsWith(validPrefix)) { return; } } string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_LINK_URL_WRONG_TYPE_2_0_1, RSS_ELEMENT_URL, this.URL); throw new SyndicationValidationException(msg); } }
protected virtual RssVersion GetVersion() { // Checking the version // Example: <rss version="2.0"> IEnumerable <XElement> rssXElement; IEnumerable <XAttribute> versionXAttribute; string rssVersionString; rssXElement = rssXml.DescendantsAndSelf((XName)"rss"); versionXAttribute = rssXElement.Attributes((XName)"version"); // need to check the behaviour of Current rssVersionString = versionXAttribute.GetEnumerator().Current.Value; switch (rssVersionString) { case "1.0": rssVersion = RssVersion.v10; break; case "2.0": rssVersion = RssVersion.v20; break; } }
/// <summary>Writes the begining data to the RSS file</summary> /// <remarks>This routine is called from the WriteChannel and WriteItem subs</remarks> /// <exception cref="NotSupportedException">RDF Site Summary (RSS) 1.0 is not currently supported.</exception> private void BeginDocument() { if (!wroteStartDocument) { if (rssVersion == RssVersion.Empty) { rssVersion = RssVersion.RSS20; } writer.Formatting = xmlFormat; writer.Indentation = xmlIndentation; writer.WriteStartDocument(); //TODO: GJ: customise the style //writer.WriteProcessingInstruction("xml-stylesheet", @"type=""text/xml"" href=""/static/rss/rss.xsl"""); //writer.WriteProcessingInstruction("xml-stylesheet", @"type=""text/css"" href=""/static/rss/rss.css"""); if (rssVersion != RssVersion.RSS20) { writer.WriteComment("Generated by RSS.NET: http://rss-net.sf.net"); } //exc: The xml:space or xml:lang attribute value is invalid. switch (rssVersion) { case RssVersion.RSS090: //<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://my.netscape.com/rdf/simple/0.9/"> writer.WriteStartElement("RDF", "rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); break; case RssVersion.RSS091: writer.WriteStartElement("rss"); writer.WriteDocType("rss", "-//Netscape Communications//DTD RSS 0.91//EN", "http://my.netscape.com/publish/formats/rss-0.91.dtd", null); writer.WriteAttributeString("version", "0.91"); break; case RssVersion.RSS092: writer.WriteStartElement("rss"); writer.WriteAttributeString("version", "0.92"); break; case RssVersion.RSS10: throw new NotSupportedException("RDF Site Summary (RSS) 1.0 is not currently supported."); case RssVersion.RSS20: writer.WriteStartElement("rss"); writer.WriteAttributeString("version", "2.0"); // RSS Modules foreach (RssModule rssModule in this._rssModules) { WriteAttribute("xmlns:" + rssModule.NamespacePrefix, rssModule.NamespaceURL.ToString(), true); } break; } wroteStartDocument = true; } }
/// <summary> /// Validates the collection. /// </summary> /// <param name="version"></param> /// <param name="validateContent"></param> /// <returns></returns> internal bool Validate(RssVersion version, bool validateContent) { foreach (RssItem item in this) { item.Validate(version, validateContent); } return(true); }
/// <summary> /// Saves the RSS object according to the version and encoding arguments. /// </summary> /// <param name="filename"></param> /// <param name="version"></param> /// <param name="encoding"></param> public void Save(string filename, RssVersion version, string encoding) { if (filename == null) { throw new ArgumentNullException("filename"); } this.Save(version, encoding).Save(filename); }
/// <summary> /// Saves the RSS object according to the version and encoding arguments. /// </summary> /// <param name="stream"></param> /// <param name="version"></param> /// <param name="encoding"></param> /// <returns></returns> public void Save(System.IO.Stream stream, RssVersion version, string encoding) { if (stream == null) { throw new ArgumentNullException("stream"); } this.Save(version, encoding).Save(stream); }
internal bool Validate(RssVersion version, bool validateContent) { foreach (RssSkipDay skipDay in this) { skipDay.Validate(version, validateContent); } return(true); }
/// <summary> /// Validates the collection. /// </summary> /// <param name="version"></param> /// <param name="validateContent"></param> /// <returns></returns> internal bool Validate(RssVersion version, bool validateContent) { foreach (RssCategory category in this) { category.Validate(version, validateContent); } return(true); }
private void ValidateDomain(RssVersion version) { if (this.Domain == null) { return; } // // All values ok. // }
/// <summary> /// Validates category. /// </summary> /// <param name="version"></param> private void ValidateCategory(RssVersion version) { if (this.Category == null) { return; } // // All values ok. // }
/// <summary> /// Validate Url. /// </summary> /// <param name="version"></param> private void ValidateGuid(RssVersion version) { if (this.GUID == null) { return; } // // All values ok. // }
/// <summary> /// Validate type. /// </summary> /// <param name="version"></param> private void ValidateType(RssVersion version) { if (this.Type == null) { return; } // // All types are valid. // }
public void RenderArchiveRss(RssVersion version, string output, int end) { foreach (DictionaryEntry de in category_entries) { string category = de.Key.ToString(); IList entries = (IList)de.Value; RenderRSS(Path.Combine(config.Prefix, "archive" + category + output), entries, 0, Math.Min(end, entries.Count)); } }
/// <summary> /// Serializes the collection to XML. /// </summary> /// <param name="xdRss"></param> /// <returns></returns> internal XmlNode SerializeToXml(XmlDocument xdRss, RssVersion version) { XmlElement xeSkipHours = xdRss.CreateElement(RSS_ELEMENT_SKIPHOURS); foreach (RssSkipHour skipHour in this) { xeSkipHours.AppendChild(skipHour.SerializeToXml(xdRss, version)); } return(xeSkipHours); }
/// <summary> /// /// </summary> /// <param name="version"></param> private void ValidateDescription(RssVersion version) { if (this.Description == null) { return; } // // All values ok. // }
private void ValidatePath(RssVersion version) { if (this.Path == null) { return; } // // All values ok. // }
/// <summary> /// Validates Comments element. /// </summary> /// <param name="version"></param> private void ValidateComments(RssVersion version) { if (this.Comments == null) { return; } // // All values ok. // }
/// <summary> /// Validates Author element. /// </summary> /// <param name="version"></param> private void ValidateAuthor(RssVersion version) { if (this.Author == null) { return; } // // All values ok. // }
/// <summary> /// /// </summary> /// <param name="version"></param> private void ValidateSource(RssVersion version) { if (this.Source == null) { return; } // // All Values Ok. // }
/// <summary> /// /// </summary> /// <param name="version"></param> private void ValidateRegisterProcuedure(RssVersion version) { if (this.RegisterProcedure == null) { return; } // // All values ok. // }
/// <summary> /// Validate width. /// </summary> /// <param name="version"></param> private void ValidateWidth(RssVersion version) { if (this.Width == null) { return; } if (version == RssVersion.RSS_0_91) { try { int width = Convert.ToInt32(this.Width); if (width < 0 || width > RSS_MAXVALUE_WIDTH_0_91) { string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_FAILED, RSS_ELEMENT_IMAGE, RSS_ELEMENT_WIDTH); throw new SyndicationValidationException(msg); } } catch (FormatException) { string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_FAILED, RSS_ELEMENT_IMAGE, RSS_ELEMENT_WIDTH); throw new SyndicationValidationException(msg); } } else if (version == RssVersion.RSS_0_92) { try { int width = Convert.ToInt32(this.Width); if (width < 0 || width > RSS_MAXVALUE_WIDTH_0_92) { string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_FAILED, RSS_ELEMENT_IMAGE, RSS_ELEMENT_WIDTH); throw new SyndicationValidationException(msg); } } catch (FormatException) { string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_FAILED, RSS_ELEMENT_IMAGE, RSS_ELEMENT_WIDTH); throw new SyndicationValidationException(msg); } } else if (version == RssVersion.RSS_2_0_1) { try { int width = Convert.ToInt32(this.Width); if (width < 0 || width > RSS_MAXVALUE_WIDTH_2_0) { string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_FAILED, RSS_ELEMENT_IMAGE, RSS_ELEMENT_WIDTH); throw new SyndicationValidationException(msg); } } catch (FormatException) { string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_FAILED, RSS_ELEMENT_IMAGE, RSS_ELEMENT_WIDTH); throw new SyndicationValidationException(msg); } } }
private void ValidateHeight(RssVersion version) { if (this.Height == null) { return; } if (version == RssVersion.RSS_0_91) { try { int height = Convert.ToInt32(this.Height); if (height < 0 || height > RSS_MAXVALUE_HEIGHT_0_91) { string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_FAILED, RSS_ELEMENT_IMAGE, RSS_ELEMENT_WIDTH); throw new SyndicationValidationException(msg); } } catch (FormatException) { string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_FAILED, RSS_ELEMENT_IMAGE, RSS_ELEMENT_WIDTH); throw new SyndicationValidationException(msg); } } else if (version == RssVersion.RSS_0_92) { try { int height = Convert.ToInt32(this.Height); if (height < 0 || height > RSS_MAXVALUE_HEIGHT_0_92) { string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_FAILED, RSS_ELEMENT_IMAGE, RSS_ELEMENT_WIDTH); throw new SyndicationValidationException(msg); } } catch (FormatException) { string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_FAILED, RSS_ELEMENT_IMAGE, RSS_ELEMENT_WIDTH); throw new SyndicationValidationException(msg); } } else if (version == RssVersion.RSS_2_0_1) { try { int height = Convert.ToInt32(this.Height); if (height < 0 || height > RSS_MAXVALUE_HEIGHT_2_0) { string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_FAILED, RSS_ELEMENT_IMAGE, RSS_ELEMENT_WIDTH); throw new SyndicationValidationException(msg); } } catch (FormatException) { string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_FAILED, RSS_ELEMENT_IMAGE, RSS_ELEMENT_WIDTH); throw new SyndicationValidationException(msg); } } }
// constants /// <summary> /// Writes the begining data to the RSS file /// </summary> /// <remarks> /// This routine is called from the WriteChannel and WriteItem subs /// </remarks> /// <exception cref="NotSupportedException">RDF Site Summary (RSS) 1.0 is not currently supported.</exception> private void BeginDocument() { if (!this.wroteStartDocument) { if (this.rssVersion == RssVersion.Empty) { this.rssVersion = RssVersion.RSS20; } this.writer.Formatting = this.xmlFormat; this.writer.Indentation = this.xmlIndentation; this.writer.WriteStartDocument(); if (this.rssVersion != RssVersion.RSS20) { this.writer.WriteComment("Generated by RSS.NET: http://rss-net.sf.net"); } //exc: The xml:space or xml:lang attribute value is invalid. switch (this.rssVersion) { case RssVersion.RSS090: //<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://my.netscape.com/rdf/simple/0.9/"> this.writer.WriteStartElement("RDF", "rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); break; case RssVersion.RSS091: this.writer.WriteStartElement("rss"); this.writer.WriteDocType("rss", "-//Netscape Communications//DTD RSS 0.91//EN", "http://my.netscape.com/publish/formats/rss-0.91.dtd", null); this.writer.WriteAttributeString("version", "0.91"); break; case RssVersion.RSS092: this.writer.WriteStartElement("rss"); this.writer.WriteAttributeString("version", "0.92"); break; case RssVersion.RSS10: throw new NotSupportedException("RDF Site Summary (RSS) 1.0 is not currently supported."); case RssVersion.RSS20: this.writer.WriteStartElement("rss"); this.writer.WriteAttributeString("version", "2.0"); // RSS Modules foreach (RssModule rssModule in this._rssModules) { WriteAttribute("xmlns:" + rssModule.NamespacePrefix, rssModule.NamespaceUrl.ToString(), true); } break; } this.wroteStartDocument = true; } }
public static IRssParser Create(RssVersion version) { switch (version) { case RssVersion.Rss_0_90: return new Rss_0_90_Parser(); case RssVersion.Rss_0_91: return new Rss_0_91_Parser(); case RssVersion.Rss_0_92: return new Rss_0_92_Parser(); case RssVersion.Rss_1_0: return new Rss_1_0_Parser(); case RssVersion.Rss_2_0: return new Rss_2_0_Parser(); case RssVersion.Atom: return new AtomParser(); } throw new InvalidOperationException(); }
public static RssWriter Create(RssVersion version) { switch (version) { case RssVersion.Rss_0_90: return new Rss_0_90_Writer(); case RssVersion.Rss_0_91: return new Rss_0_91_Writer(); case RssVersion.Rss_1_0: return new Rss_1_0_Writer(); case RssVersion.Rss_0_92: case RssVersion.Rss_2_0: case RssVersion.Atom: default: throw new InvalidOperationException(); } }
/// <summary> /// Validate Link. /// </summary> /// <param name="version"></param> private void ValidateLink(RssVersion version) { if (this.Link == null) { return; } if (version == RssVersion.RSS_0_91) { if (this.Link.Length > RSS_MAXLENGTH_LINK_0_91) { string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_LINK_URL_WRONG_TYPE_0_91, RSS_ELEMENT_LINK, this.Link); throw new SyndicationValidationException(msg); } string link = this.Link.ToLower().Trim(); foreach (string validPrefix in Rss.RSS_VALIDVALUES_LINK_URL_0_91) { if (link.StartsWith(validPrefix)) { return; } } string msg2 = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_LINK_URL_WRONG_TYPE_0_91, RSS_ELEMENT_LINK, this.Link); throw new SyndicationValidationException(msg2); } // if else if (version == RssVersion.RSS_0_92) { string link = this.Link.ToLower().Trim(); foreach (string validPrefix in Rss.RSS_VALIDVALUES_LINK_URL_0_92) { if (link.StartsWith(validPrefix)) { return; } } string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_LINK_URL_WRONG_TYPE_0_92, RSS_ELEMENT_LINK, this.Link); throw new SyndicationValidationException(msg); } // if else if (version == RssVersion.RSS_2_0_1) { string link = this.Link.ToLower().Trim(); foreach (string validPrefix in Rss.RSS_VALIDVALUES_LINK_URL_2_0_1) { if (link.StartsWith(validPrefix)) { return; } } string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_LINK_URL_WRONG_TYPE_2_0_1, RSS_ELEMENT_LINK, this.Link); throw new SyndicationValidationException(msg); } }
/// <summary> /// Validate type. /// </summary> /// <param name="version"></param> private void ValidateIsPermaLink(RssVersion version) { if (this.IsPermaLink == null) { return; } try { bool isPermaLink = Convert.ToBoolean(this.IsPermaLink); } catch (FormatException) { string msg = string.Format(Rss.RSS_ERRORMESSAGE_VALIDATION_FAILED, RSS_ELEMENT_GUID, RSS_ELEMENT_ISPERMALINK); throw new SyndicationValidationException(msg); } }
private static RssWriter Create(XmlTextWriter writer, RssVersion version) { RssWriter rssWriter = null; switch (version) { case RssVersion.RSS20: rssWriter = new Rss20Writer(writer); break; default: throw new NotSupportedException("The specified RSS version is not currently supported."); } return(rssWriter); }
/// <summary>Creates an instance of the RssWriter class using the specified file.</summary> /// <remarks>The encoding is ISO-8859-1 and the version is RSS 2.0.</remarks> /// <exception cref="ArgumentException">The filename is empty, contains only white space, or contains one or more invalid characters.</exception> /// <exception cref="UnauthorizedAccessException">Access is denied.</exception> /// <exception cref="ArgumentNullException">The filename is a (null c#, Nothing vb) reference.</exception> /// <exception cref="DirectoryNotFoundException">The directory to write to is not found.</exception> /// <exception cref="IOException">The filename includes an incorrect or invalid syntax for file name, directory name, or volume label syntax.</exception> /// <exception cref="System.Security.SecurityException">The caller does not have the required permission.</exception> /// <param name="fileName">specified file (including path) If the file exists, it will be truncated with the new content.</param> /// <param name="version">the RSS version to output.</param> /// <returns>The new instance.</returns> public static RssWriter Create(string fileName, RssVersion version) { return RssWriter.Create(new XmlTextWriter(fileName, DefaultEncoding), DefaultRssVersion); }
/// <summary>Creates an instance of the RssWriter class using the specified file and Encoding.</summary> /// <exception cref="ArgumentException">The encoding is not supported; the filename is empty, contains only white space, or contains one or more invalid characters.</exception> /// <exception cref="UnauthorizedAccessException">Access is denied.</exception> /// <exception cref="ArgumentNullException">The filename is a (null c#, Nothing vb) reference.</exception> /// <exception cref="DirectoryNotFoundException">The directory to write to is not found.</exception> /// <exception cref="IOException">The filename includes an incorrect or invalid syntax for file name, directory name, or volume label syntax.</exception> /// <exception cref="System.Security.SecurityException">The caller does not have the required permission.</exception> /// <param name="fileName">specified file (including path) If the file exists, it will be truncated with the new content.</param> /// <param name="version">the RSS version for output.</param> /// <param name="encoding">specified Encoding</param> public static RssWriter Create(string fileName, RssVersion version, Encoding encoding) { return RssWriter.Create(new XmlTextWriter(fileName, encoding), version); }
/// <summary> /// Reads the next RssElement from the stream. /// </summary> /// <returns> An RSS Element </returns> /// <exception cref="InvalidOperationException">RssReader has been closed, and can not be read.</exception> /// <exception cref="System.IO.FileNotFoundException">RSS file not found.</exception> /// <exception cref="System.Xml.XmlException">Invalid XML syntax in RSS file.</exception> /// <exception cref="System.IO.EndOfStreamException">Unable to read an RssElement. Reached the end of the stream.</exception> public RssElement Read() { bool readData = false; RssElement rssElement = null; int lineNumber = -1; int linePosition = -1; if (this.reader == null) throw new InvalidOperationException("RssReader has been closed, and can not be read."); do { bool pushElement = true; try { readData = this.reader.Read(); } catch (EndOfStreamException e) { throw new EndOfStreamException("Unable to read an RssElement. Reached the end of the stream.", e); } catch (XmlException e) { if (lineNumber != -1 || linePosition != -1) if (this.reader.LineNumber == lineNumber && this.reader.LinePosition == linePosition) throw this.exceptions.LastException; lineNumber = this.reader.LineNumber; linePosition = this.reader.LinePosition; this.exceptions.Add(e); // just add to list of exceptions and continue :) } if (readData) { string readerName = this.reader.Name.ToLower(); switch (this.reader.NodeType) { case XmlNodeType.Element: { //if (reader.IsEmptyElement) // break; // doesnt take empty elements into account :/ this.elementText = new StringBuilder(); switch (readerName) { case "item": // is this the end of the channel element? (absence of </channel> before <item>) if (!this.wroteChannel) { this.wroteChannel = true; rssElement = this.channel; // return RssChannel readData = false; } this.item = new RssItem.RssItem(); // create new RssItem this.channel.Items.Add(this.item); break; case "source": this.source = new RssSource(); this.item.Source = this.source; for (int i = 0; i < this.reader.AttributeCount; i++) { this.reader.MoveToAttribute(i); switch (this.reader.Name.ToLower()) { case "url": try { this.source.Url = new Uri(this.reader.Value); } catch (Exception e) { this.exceptions.Add(e); } break; } } break; case "enclosure": this.enclosure = new RssEnclosure(); this.item.Enclosure = this.enclosure; for (int i = 0; i < this.reader.AttributeCount; i++) { this.reader.MoveToAttribute(i); switch (this.reader.Name.ToLower()) { case "url": try { this.enclosure.Url = new Uri(this.reader.Value); } catch (Exception e) { this.exceptions.Add(e); } break; case "length": try { this.enclosure.Length = int.Parse(this.reader.Value); } catch (Exception e) { this.exceptions.Add(e); } break; case "type": this.enclosure.Type = this.reader.Value; break; } } break; case "guid": this.guid = new RssGuid(); this.item.Guid = this.guid; for (int i = 0; i < this.reader.AttributeCount; i++) { this.reader.MoveToAttribute(i); switch (this.reader.Name.ToLower()) { case "ispermalink": try { this.guid.PermaLink = bool.Parse(this.reader.Value); } catch (Exception e) { this.exceptions.Add(e); } break; } } break; case "category": this.category = new RssCategory(); if ((string) this.xmlNodeStack.Peek() == "channel") this.channel.Categories.Add(this.category); else this.item.Categories.Add(this.category); for (int i = 0; i < this.reader.AttributeCount; i++) { this.reader.MoveToAttribute(i); switch (this.reader.Name.ToLower()) { case "url": goto case "domain"; case "domain": this.category.Domain = this.reader.Value; break; } } break; case "channel": this.channel = new RssChannel.RssChannel(); this.textInput = null; this.image = null; this.cloud = null; this.source = null; this.enclosure = null; this.category = null; this.item = null; break; case "image": this.image = new RssImage(); this.channel.Image = this.image; break; case "textinput": this.textInput = new RssTextInput(); this.channel.TextInput = this.textInput; break; case "cloud": pushElement = false; this.cloud = new RssCloud(); this.channel.Cloud = this.cloud; for (int i = 0; i < this.reader.AttributeCount; i++) { this.reader.MoveToAttribute(i); switch (this.reader.Name.ToLower()) { case "domain": this.cloud.Domain = this.reader.Value; break; case "port": try { this.cloud.Port = ushort.Parse(this.reader.Value); } catch (Exception e) { this.exceptions.Add(e); } break; case "path": this.cloud.Path = this.reader.Value; break; case "registerprocedure": this.cloud.RegisterProcedure = this.reader.Value; break; case "protocol": switch (this.reader.Value.ToLower()) { case "xml-rpc": this.cloud.Protocol = RssCloudProtocol.XmlRpc; break; case "soap": this.cloud.Protocol = RssCloudProtocol.Soap; break; case "http-post": this.cloud.Protocol = RssCloudProtocol.HttpPost; break; default: this.cloud.Protocol = RssCloudProtocol.Empty; break; } break; } } break; case "rss": for (int i = 0; i < this.reader.AttributeCount; i++) { this.reader.MoveToAttribute(i); if (this.reader.Name.ToLower() == "version") switch (this.reader.Value) { case "0.91": this.rssVersion = RssVersion.RSS091; break; case "0.92": this.rssVersion = RssVersion.RSS092; break; case "2.0": this.rssVersion = RssVersion.RSS20; break; default: this.rssVersion = RssVersion.NotSupported; break; } } break; case "rdf": for (int i = 0; i < this.reader.AttributeCount; i++) { this.reader.MoveToAttribute(i); if (this.reader.Name.ToLower() == "version") switch (this.reader.Value) { case "0.90": this.rssVersion = RssVersion.RSS090; break; case "1.0": this.rssVersion = RssVersion.RSS10; break; default: this.rssVersion = RssVersion.NotSupported; break; } } break; } if (pushElement) this.xmlNodeStack.Push(readerName); break; } case XmlNodeType.EndElement: { if (this.xmlNodeStack.Count == 1) break; string childElementName = (string) this.xmlNodeStack.Pop(); string parentElementName = (string) this.xmlNodeStack.Peek(); switch (childElementName) // current element { // item classes case "item": rssElement = this.item; readData = false; break; case "source": this.source.Name = this.elementText.ToString(); rssElement = this.source; readData = false; break; case "enclosure": rssElement = this.enclosure; readData = false; break; case "guid": this.guid.Name = this.elementText.ToString(); rssElement = this.guid; readData = false; break; case "category": // parent is either item or channel this.category.Name = this.elementText.ToString(); rssElement = this.category; readData = false; break; // channel classes case "channel": if (this.wroteChannel) this.wroteChannel = false; else { this.wroteChannel = true; rssElement = this.channel; readData = false; } break; case "textinput": rssElement = this.textInput; readData = false; break; case "image": rssElement = this.image; readData = false; break; case "cloud": rssElement = this.cloud; readData = false; break; } switch (parentElementName) // parent element { case "item": switch (childElementName) { case "title": this.item.Title = this.elementText.ToString(); break; case "link": this.item.Link = new Uri(this.elementText.ToString()); break; case "description": this.item.Description = this.elementText.ToString(); break; case "author": this.item.Author = this.elementText.ToString(); break; case "comments": this.item.Comments = this.elementText.ToString(); break; case "pubdate": try { this.item.PubDate = DateTime.Parse(this.elementText.ToString()); } catch (Exception e) { try { string tmp = this.elementText.ToString(); tmp = tmp.Substring(0, tmp.Length - 5); tmp += "GMT"; this.item.PubDate = DateTime.Parse(tmp); } catch { this.exceptions.Add(e); } } break; } break; case "channel": switch (childElementName) { case "title": this.channel.Title = this.elementText.ToString(); break; case "link": try { this.channel.Link = new Uri(this.elementText.ToString()); } catch (Exception e) { this.exceptions.Add(e); } break; case "description": this.channel.Description = this.elementText.ToString(); break; case "language": this.channel.Language = this.elementText.ToString(); break; case "copyright": this.channel.Copyright = this.elementText.ToString(); break; case "managingeditor": this.channel.ManagingEditor = this.elementText.ToString(); break; case "webmaster": this.channel.WebMaster = this.elementText.ToString(); break; case "rating": this.channel.Rating = this.elementText.ToString(); break; case "pubdate": try { this.channel.PubDate = DateTime.Parse(this.elementText.ToString()); } catch (Exception e) { this.exceptions.Add(e); } break; case "lastbuilddate": try { this.channel.LastBuildDate = DateTime.Parse(this.elementText.ToString()); } catch (Exception e) { this.exceptions.Add(e); } break; case "generator": this.channel.Generator = this.elementText.ToString(); break; case "docs": this.channel.Docs = this.elementText.ToString(); break; case "ttl": try { this.channel.TimeToLive = int.Parse(this.elementText.ToString()); } catch (Exception e) { this.exceptions.Add(e); } break; } break; case "image": switch (childElementName) { case "url": try { this.image.Url = new Uri(this.elementText.ToString()); } catch (Exception e) { this.exceptions.Add(e); } break; case "title": this.image.Title = this.elementText.ToString(); break; case "link": try { this.image.Link = new Uri(this.elementText.ToString()); } catch (Exception e) { this.exceptions.Add(e); } break; case "description": this.image.Description = this.elementText.ToString(); break; case "width": try { this.image.Width = Byte.Parse(this.elementText.ToString()); } catch (Exception e) { this.exceptions.Add(e); } break; case "height": try { this.image.Height = Byte.Parse(this.elementText.ToString()); } catch (Exception e) { this.exceptions.Add(e); } break; } break; case "textinput": switch (childElementName) { case "title": this.textInput.Title = this.elementText.ToString(); break; case "description": this.textInput.Description = this.elementText.ToString(); break; case "name": this.textInput.Name = this.elementText.ToString(); break; case "link": try { this.textInput.Link = new Uri(this.elementText.ToString()); } catch (Exception e) { this.exceptions.Add(e); } break; } break; case "skipdays": if (childElementName == "day") switch (this.elementText.ToString().ToLower()) { case "monday": this.channel.SkipDays[0] = true; break; case "tuesday": this.channel.SkipDays[1] = true; break; case "wednesday": this.channel.SkipDays[2] = true; break; case "thursday": this.channel.SkipDays[3] = true; break; case "friday": this.channel.SkipDays[4] = true; break; case "saturday": this.channel.SkipDays[5] = true; break; case "sunday": this.channel.SkipDays[6] = true; break; } break; case "skiphours": if (childElementName == "hour") this.channel.SkipHours[Byte.Parse(this.elementText.ToString().ToLower())] = true; break; } break; } case XmlNodeType.Text: this.elementText.Append(this.reader.Value); break; case XmlNodeType.CDATA: this.elementText.Append(this.reader.Value); break; } } } while (readData); return rssElement; }
// constants /// <summary> /// Writes the begining data to the RSS file /// </summary> /// <remarks> /// This routine is called from the WriteChannel and WriteItem subs /// </remarks> /// <exception cref="NotSupportedException">RDF Site Summary (RSS) 1.0 is not currently supported.</exception> private void BeginDocument() { if (!this.wroteStartDocument) { if (this.rssVersion == RssVersion.Empty) this.rssVersion = RssVersion.RSS20; this.writer.Formatting = this.xmlFormat; this.writer.Indentation = this.xmlIndentation; this.writer.WriteStartDocument(); if (this.rssVersion != RssVersion.RSS20) this.writer.WriteComment("Generated by RSS.NET: http://rss-net.sf.net"); //exc: The xml:space or xml:lang attribute value is invalid. switch (this.rssVersion) { case RssVersion.RSS090: //<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://my.netscape.com/rdf/simple/0.9/"> this.writer.WriteStartElement("RDF", "rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); break; case RssVersion.RSS091: this.writer.WriteStartElement("rss"); this.writer.WriteDocType("rss", "-//Netscape Communications//DTD RSS 0.91//EN", "http://my.netscape.com/publish/formats/rss-0.91.dtd", null); this.writer.WriteAttributeString("version", "0.91"); break; case RssVersion.RSS092: this.writer.WriteStartElement("rss"); this.writer.WriteAttributeString("version", "0.92"); break; case RssVersion.RSS10: throw new NotSupportedException("RDF Site Summary (RSS) 1.0 is not currently supported."); case RssVersion.RSS20: this.writer.WriteStartElement("rss"); this.writer.WriteAttributeString("version", "2.0"); // RSS Modules foreach (RssModule rssModule in this._rssModules) { WriteAttribute("xmlns:" + rssModule.NamespacePrefix, rssModule.NamespaceUrl.ToString(), true); } break; } this.wroteStartDocument = true; } }
/// <summary>Writes the begining data to the RSS file</summary> /// <remarks>This routine is called from the WriteChannel and WriteItem subs</remarks> /// <exception cref="NotSupportedException">RDF Site Summary (RSS) 1.0 is not currently supported.</exception> private void BeginDocument() { if (!wroteStartDocument) { if (rssVersion == RssVersion.Empty) rssVersion = RssVersion.RSS20; writer.Formatting = xmlFormat; writer.Indentation = xmlIndentation; writer.WriteStartDocument(); //TODO: GJ: customise the style //writer.WriteProcessingInstruction("xml-stylesheet", @"type=""text/xml"" href=""/static/rss/rss.xsl"""); //writer.WriteProcessingInstruction("xml-stylesheet", @"type=""text/css"" href=""/static/rss/rss.css"""); if (rssVersion != RssVersion.RSS20) writer.WriteComment("Generated by RSS.NET: http://rss-net.sf.net"); //exc: The xml:space or xml:lang attribute value is invalid. switch (rssVersion) { case RssVersion.RSS090: //<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://my.netscape.com/rdf/simple/0.9/"> writer.WriteStartElement("RDF", "rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); break; case RssVersion.RSS091: writer.WriteStartElement("rss"); writer.WriteDocType("rss", "-//Netscape Communications//DTD RSS 0.91//EN", "http://my.netscape.com/publish/formats/rss-0.91.dtd", null); writer.WriteAttributeString("version", "0.91"); break; case RssVersion.RSS092: writer.WriteStartElement("rss"); writer.WriteAttributeString("version", "0.92"); break; case RssVersion.RSS10: throw new NotSupportedException("RDF Site Summary (RSS) 1.0 is not currently supported."); case RssVersion.RSS20: writer.WriteStartElement("rss"); writer.WriteAttributeString("version", "2.0"); // RSS Modules foreach(RssModule rssModule in this._rssModules) { WriteAttribute("xmlns:" + rssModule.NamespacePrefix, rssModule.NamespaceURL.ToString(), true); } break; } wroteStartDocument = true; } }
private static RssWriter Create(XmlTextWriter writer, RssVersion version) { RssWriter rssWriter = null; switch(version) { case RssVersion.RSS20: rssWriter = new Rss20Writer(writer); break; default: throw new NotSupportedException("The specified RSS version is not currently supported."); } return rssWriter; }
/// <summary>Creates an instance of the RssWriter class using the specified TextWriter.</summary> /// <param name="textWriter">specified TextWriter</param> /// <param name="version">The RSS version for output.</param> public static RssWriter Create(TextWriter textWriter, RssVersion version) { return RssWriter.Create(new XmlTextWriter(textWriter), version); }
/// <summary>Creates an instance of the RssWriter class using the specified Stream and Encoding.</summary> /// <exception cref="ArgumentException">The encoding is not supported or the stream cannot be written to.</exception> /// <param name="stream">Stream to output to</param> /// <param name="version">The RSS version for output.</param> /// <param name="encoding">The encoding to use. If encoding is (null c#, Nothing vb) it writes out the stream as UTF-8.</param> /// <returns>The new instance.</returns> public static RssWriter Create(Stream stream, RssVersion version, Encoding encoding) { return RssWriter.Create(new XmlTextWriter(stream, encoding), version); }
/// <summary>Creates an instance of the RssWriter class using the specified Stream, and encoded to ISO-8859-1.</summary> /// <param name="stream">Stream to output to</param> /// <param name="version">The RSS version for output.</param> /// <returns>The new instance.</returns> public static RssWriter Create(Stream stream, RssVersion version) { return RssWriter.Create(stream, version, DefaultEncoding); }
public void RenderArchiveRss(RssVersion version, string output, int end) { foreach (DictionaryEntry de in category_entries) { string category = de.Key.ToString (); IList entries = (IList) de.Value; RenderRSS (Path.Combine (config.Prefix, "archive" + category + output), entries, 0, Math.Min (end, entries.Count)); } }
/// <summary>Reads the next RssElement from the stream.</summary> /// <returns>An RSS Element</returns> /// <exception cref="InvalidOperationException">RssReader has been closed, and can not be read.</exception> /// <exception cref="System.IO.FileNotFoundException">RSS file not found.</exception> /// <exception cref="System.Xml.XmlException">Invalid XML syntax in RSS file.</exception> /// <exception cref="System.IO.EndOfStreamException">Unable to read an RssElement. Reached the end of the stream.</exception> public RssElement Read() { bool readData = false; bool pushElement = true; RssElement rssElement = null; int lineNumber = -1; int linePosition = -1; if (reader == null) throw new InvalidOperationException("RssReader has been closed, and can not be read."); do { pushElement = true; try { readData = reader.Read(); } catch (System.IO.EndOfStreamException e) { throw new System.IO.EndOfStreamException("Unable to read an RssElement. Reached the end of the stream.", e); } catch (System.Xml.XmlException e) { if (lineNumber != -1 || linePosition != -1) if (reader.LineNumber == lineNumber && reader.LinePosition == linePosition) throw exceptions.LastException; lineNumber = reader.LineNumber; linePosition = reader.LinePosition; exceptions.Add(e); // just add to list of exceptions and continue :) //// Added, OFxP //if (readData) //{ // continue; //} } if (readData) { string readerName = reader.Name.ToLower(); switch (reader.NodeType) { case XmlNodeType.Element: { if (reader.IsEmptyElement) break; elementText = new StringBuilder(); switch (readerName) { case "item": // is this the end of the channel element? (absence of </channel> before <item>) if (!wroteChannel) { wroteChannel = true; rssElement = channel; // return RssChannel readData = false; } item = new RssItem(); // create new RssItem channel.Items.Add(item); break; case "source": source = new RssSource(); item.Source = source; for (int i=0; i < reader.AttributeCount; i++) { reader.MoveToAttribute(i); switch (reader.Name.ToLower()) { case "url": try { // OFxP, fix //source.Url = new Uri(reader.Value); source.Url = new Uri(reader.Value, true); } catch (Exception e) { exceptions.Add(e); } break; } } break; case "enclosure": enclosure = new RssEnclosure(); item.Enclosure = enclosure; for (int i=0; i < reader.AttributeCount; i++) { reader.MoveToAttribute(i); switch (reader.Name.ToLower()) { case "url": try { // OFxP, fix //enclosure.Url = new Uri(reader.Value); enclosure.Url = new Uri(reader.Value, true); } catch (Exception e) { exceptions.Add(e); } break; case "length": try { enclosure.Length = int.Parse(reader.Value); } catch (Exception e) { exceptions.Add(e); } break; case "type": enclosure.Type = reader.Value; break; } } break; case "guid": guid = new RssGuid(); item.Guid = guid; for (int i=0; i < reader.AttributeCount; i++) { reader.MoveToAttribute(i); switch (reader.Name.ToLower()) { case "ispermalink": try { guid.PermaLink = bool.Parse(reader.Value); } catch (Exception e) { exceptions.Add(e); } break; } } break; case "category": category = new RssCategory(); if ((string)xmlNodeStack.Peek() == "channel") channel.Categories.Add(category); else item.Categories.Add(category); for (int i=0; i < reader.AttributeCount; i++) { reader.MoveToAttribute(i); switch (reader.Name.ToLower()) { case "url": goto case "domain"; case "domain": category.Domain = reader.Value; break; } } break; case "channel": channel = new RssChannel(); textInput = null; image = null; cloud = null; source = null; enclosure = null; category = null; item = null; break; case "image": image = new RssImage(); channel.Image = image; break; case "textinput": textInput = new RssTextInput(); channel.TextInput = textInput; break; case "cloud": pushElement = false; cloud = new RssCloud(); channel.Cloud = cloud; for (int i=0; i < reader.AttributeCount; i++) { reader.MoveToAttribute(i); switch (reader.Name.ToLower()) { case "domain": cloud.Domain = reader.Value; break; case "port": try { cloud.Port = ushort.Parse(reader.Value); } catch (Exception e) { exceptions.Add(e); } break; case "path": cloud.Path = reader.Value; break; case "registerprocedure": cloud.RegisterProcedure = reader.Value; break; case "protocol": switch (reader.Value.ToLower()) { case "xml-rpc": cloud.Protocol = RssCloudProtocol.XmlRpc; break; case "soap": cloud.Protocol = RssCloudProtocol.Soap; break; case "http-post": cloud.Protocol = RssCloudProtocol.HttpPost; break; default: cloud.Protocol = RssCloudProtocol.Empty; break; } break; } } break; case "rss": for (int i=0; i < reader.AttributeCount; i++) { reader.MoveToAttribute(i); if (reader.Name.ToLower() == "version") switch (reader.Value) { case "0.91": rssVersion = RssVersion.RSS091; break; case "0.92": rssVersion = RssVersion.RSS092; break; case "2.0": rssVersion = RssVersion.RSS20; break; default: rssVersion = RssVersion.NotSupported; break; } } break; case "rdf": for (int i=0; i < reader.AttributeCount; i++) { reader.MoveToAttribute(i); if (reader.Name.ToLower() == "version") switch (reader.Value) { case "0.90": rssVersion = RssVersion.RSS090; break; case "1.0": rssVersion = RssVersion.RSS10; break; default: rssVersion = RssVersion.NotSupported; break; } } break; } if (pushElement) xmlNodeStack.Push(readerName); break; } case XmlNodeType.EndElement: { if (xmlNodeStack.Count == 1) break; string childElementName = (string)xmlNodeStack.Pop(); string parentElementName = (string)xmlNodeStack.Peek(); switch (childElementName) // current element { // item classes case "item": rssElement = item; readData = false; break; case "source": source.Name = elementText.ToString(); rssElement = source; readData = false; break; case "enclosure": rssElement = enclosure; readData = false; break; case "guid": guid.Name = elementText.ToString(); rssElement = guid; readData = false; break; case "category": // parent is either item or channel category.Name = elementText.ToString(); rssElement = category; readData = false; break; // channel classes case "channel": if (wroteChannel) wroteChannel = false; else { wroteChannel = true; rssElement = channel; readData = false; } break; case "textinput": rssElement = textInput; readData = false; break; case "image": rssElement = image; readData = false; break; case "cloud": rssElement = cloud; readData = false; break; } switch (parentElementName) // parent element { case "item": switch (childElementName) { case "title": item.Title = elementText.ToString(); break; case "link": // OFxP, fix //item.Link = new Uri(elementText.ToString()); item.Link = new Uri(elementText.ToString(), true); break; case "description": item.Description = elementText.ToString(); break; case "author": item.Author = elementText.ToString(); break; case "comments": item.Comments = elementText.ToString(); break; case "dc:date": // Fix for the federalreserve feed. case "pubdate": item.PubDate = GeneralHelper.ParseDateTimeWithZone(elementText.ToString()); break; } break; case "channel": switch (childElementName) { case "title": channel.Title = elementText.ToString(); break; case "link": try { // OFxP, fix //channel.Link = new Uri(elementText.ToString()); channel.Link = new Uri(elementText.ToString(), true); } catch (Exception e) { exceptions.Add(e); } break; case "description": channel.Description = elementText.ToString(); break; case "language": channel.Language = elementText.ToString(); break; case "copyright": channel.Copyright = elementText.ToString(); break; case "managingeditor": channel.ManagingEditor = elementText.ToString(); break; case "webmaster": channel.WebMaster = elementText.ToString(); break; case "rating": channel.Rating = elementText.ToString(); break; case "dc:date": // Fix for the federalreserve feed. case "pubdate": channel.PubDate = GeneralHelper.ParseDateTimeWithZone(elementText.ToString()); break; case "lastbuilddate": channel.LastBuildDate = GeneralHelper.ParseDateTimeWithZone(elementText.ToString()); break; case "generator": channel.Generator = elementText.ToString(); break; case "docs": channel.Docs = elementText.ToString(); break; case "ttl": try { channel.TimeToLive = int.Parse(elementText.ToString()); } catch (Exception e) { exceptions.Add(e); } break; } break; case "image": switch (childElementName) { case "url": try { // OFxP, fix //image.Url = new Uri(elementText.ToString()); image.Url = new Uri(elementText.ToString(), true); } catch (Exception e) { exceptions.Add(e); } break; case "title": image.Title = elementText.ToString(); break; case "link": try { // OFxP, fix //image.Link = new Uri(elementText.ToString()); image.Link = new Uri(elementText.ToString(), true); } catch (Exception e) { exceptions.Add(e); } break; case "description": image.Description = elementText.ToString(); break; case "width": try { image.Width = Byte.Parse(elementText.ToString()); } catch (Exception e) { exceptions.Add(e); } break; case "height": try { image.Height = Byte.Parse(elementText.ToString()); } catch (Exception e) { exceptions.Add(e); } break; } break; case "textinput": switch (childElementName) { case "title": textInput.Title = elementText.ToString(); break; case "description": textInput.Description = elementText.ToString(); break; case "name": textInput.Name = elementText.ToString(); break; case "link": try { // OFxP, fix //textInput.Link = new Uri(elementText.ToString()); textInput.Link = new Uri(elementText.ToString(), true); } catch (Exception e) { exceptions.Add(e); } break; } break; case "skipdays": if (childElementName == "day") channel.SkipDays |= Day.Parse(elementText.ToString()); break; case "skiphours": if (childElementName == "hour") channel.SkipHours |= Hour.Parse(elementText.ToString()); break; } break; } case XmlNodeType.Text: elementText.Append(reader.Value); break; case XmlNodeType.CDATA: elementText.Append(reader.Value); break; } } } while (readData); return rssElement; }
// parses the rss file void readFeed(XmlDocument doc) { // make sure its a valid rss document XmlNodeList elements = doc.GetElementsByTagName ("rss"); if (elements.Count == 0) { elements = doc.GetElementsByTagName ("rdf"); if (elements.Count == 0) return; } // get the rss version string rss_version = elements [0].Attributes ["version"].Value; switch (rss_version) { case "0.90": version = RssVersion.RSS090; break; case "0.91": version = RssVersion.RSS091; break; case "0.92": version = RssVersion.RSS092; break; case "1.0": version = RssVersion.RSS10; break; case "2.0": version = RssVersion.RSS20; break; default: version = RssVersion.NotSupported; break; } // get the channels elements = doc.GetElementsByTagName ("channel"); if (elements.Count == 0) return; channel = new RssChannel (elements [0].ChildNodes); }