private async Task AddCategoriesXml(XmlElement categoriesNode, XmlElement containerNode, XmlRestRequestHelper.XmlRequestResult result) { if (categoriesNode.Attributes.Any(a => a.NodeName == "href")) { string href = XmlHelper.GetUrl(categoriesNode, "@href", result.uri); if (href != null && href.Length > 0) { Uri uri = new Uri(href); if (result.uri == null || !uri.Equals(result.uri)) // detect simple cycles { XmlDocument doc = await xmlRestRequestHelper.Get(RequestFilter, result); XmlElement categories = (XmlElement)doc.SelectSingleNodeNS(@"app:categories", _nsMgr.ToNSMethodFormat()); if (categories != null) { await AddCategoriesXml(categories, containerNode, result); } } } } else { containerNode.AppendChild(containerNode.OwnerDocument.ImportNode(categoriesNode, true)); } }
public static void AddChildWithInnerText(this Windows.Data.Xml.Dom.XmlElement rootNode, string name, string innerText) { var node = rootNode.OwnerDocument.CreateElement(name); node.InnerText = innerText; rootNode.AppendChild(node); }
// ............................................................. // // Images // // ............................................................. private static void AddImage(XmlElement xamlParentElement, XmlElement htmlElement, IDictionary inheritedProperties, CssStylesheet stylesheet, List<XmlElement> sourceContext) { string htmlImageElementName = htmlElement.LocalName.ToLower(); // Implement images IDictionary localProperties; IDictionary currentProperties = GetElementProperties(htmlElement, inheritedProperties, out localProperties, stylesheet, sourceContext); XmlElement xamlInlineUiContainer = xamlParentElement.OwnerDocument.CreateElementNS(_xamlNamespace, Xaml_InlineUIContainer); XmlElement xamlImage = xamlParentElement.OwnerDocument.CreateElementNS(_xamlNamespace, Xaml_InlineUIContainer_Image); xamlImage.SetAttribute(Xaml_Source,htmlElement.GetAttribute("src")); xamlImage.SetAttribute(Xaml_Width, htmlElement.GetAttribute("width")); // xamlImage.SetAttributeNS("App5.Utils", "utils:ADP.Source", "{Binding Text}"); xamlInlineUiContainer.AppendChild(xamlImage); xamlParentElement.AppendChild(xamlInlineUiContainer); }
private static void AddHyperlink(XmlElement xamlParentElement, XmlElement htmlElement, IDictionary inheritedProperties, CssStylesheet stylesheet, List<XmlElement> sourceContext) { // Convert href attribute into NavigateUri and TargetName string href = GetAttribute(htmlElement, "href"); if (href == null) { // When href attribute is missing - ignore the hyperlink AddSpanOrRun(xamlParentElement, htmlElement, inheritedProperties, stylesheet, sourceContext); } else { // Create currentProperties as a compilation of local and inheritedProperties, set localProperties IDictionary localProperties; IDictionary currentProperties = GetElementProperties(htmlElement, inheritedProperties, out localProperties, stylesheet, sourceContext); // Create a XAML element corresponding to this html element XmlElement xamlElement = xamlParentElement.OwnerDocument.CreateElementNS(_xamlNamespace,HtmlToXamlConverter.Xaml_Hyperlink); ApplyLocalProperties(xamlElement, localProperties, /*isBlock:*/false); string[] hrefParts = href.Split(new char[] { '#' }); if (hrefParts.Length > 0 && hrefParts[0].Trim().Length > 0) { xamlElement.SetAttribute(HtmlToXamlConverter.Xaml_Hyperlink_NavigateUri, hrefParts[0].Trim()); } if (hrefParts.Length == 2 && hrefParts[1].Trim().Length > 0) { xamlElement.SetAttribute(HtmlToXamlConverter.Xaml_Hyperlink_TargetName, hrefParts[1].Trim()); } // Recurse into element subtree for (IXmlNode htmlChildNode = htmlElement.FirstChild; htmlChildNode != null; htmlChildNode = htmlChildNode.NextSibling) { AddInline(xamlElement, htmlChildNode, currentProperties, stylesheet, sourceContext); } // Add the new element to the parent. xamlParentElement.AppendChild(xamlElement); } }
/// <summary> /// Processes the information about table columns - COLGROUP and COL html elements. /// </summary> /// <param name="htmlTableElement"> /// XmlElement representing a source html table. /// </param> /// <param name="xamlTableElement"> /// XmlElement repesenting a resulting xaml table. /// </param> /// <param name="columnStartsAllRows"> /// Array of doubles - column start coordinates. /// Can be null, which means that column size information is not available /// and we must use source colgroup/col information. /// In case wneh it's not null, we will ignore source colgroup/col information. /// </param> /// <param name="currentProperties"></param> /// <param name="stylesheet"></param> /// <param name="sourceContext"></param> private static void AddColumnInformation(XmlElement htmlTableElement, XmlElement xamlTableElement, IList columnStartsAllRows, IDictionary currentProperties, CssStylesheet stylesheet, List<XmlElement> sourceContext) { // Add column information if (columnStartsAllRows != null) { // We have consistent information derived from table cells; use it // The last element in columnStarts represents the end of the table for (int columnIndex = 0; columnIndex < columnStartsAllRows.Count - 1; columnIndex++) { XmlElement xamlColumnElement; xamlColumnElement = xamlTableElement.OwnerDocument.CreateElementNS( _xamlNamespace,Xaml_TableColumn); xamlColumnElement.SetAttribute(Xaml_Width, ((double)columnStartsAllRows[columnIndex + 1] - (double)columnStartsAllRows[columnIndex]).ToString()); xamlTableElement.AppendChild(xamlColumnElement); } } else { // We do not have consistent information from table cells; // Translate blindly colgroups from html. for (IXmlNode htmlChildNode = htmlTableElement.FirstChild; htmlChildNode != null; htmlChildNode = htmlChildNode.NextSibling) { if (htmlChildNode.LocalName.ToLower() == "colgroup") { // TODO: add column width information to this function as a parameter and process it AddTableColumnGroup(xamlTableElement, (XmlElement)htmlChildNode, currentProperties, stylesheet, sourceContext); } else if (htmlChildNode.LocalName.ToLower() == "col") { AddTableColumn(xamlTableElement, (XmlElement)htmlChildNode, currentProperties, stylesheet, sourceContext); } else if (htmlChildNode is XmlElement) { // Some element which belongs to table body. Stop column loop. break; } } } }
private static void AddSpanOrRun(XmlElement xamlParentElement, XmlElement htmlElement, IDictionary inheritedProperties, CssStylesheet stylesheet, List<XmlElement> sourceContext) { // Decide what XAML element to use for this inline element. // Check whether it contains any nested inlines bool elementHasChildren = false; for (IXmlNode htmlNode = htmlElement.FirstChild; htmlNode != null; htmlNode = htmlNode.NextSibling) { if (htmlNode is XmlElement) { string htmlChildName = ((XmlElement)htmlNode).LocalName.ToLower(); if (HtmlSchema.IsInlineElement(htmlChildName) || HtmlSchema.IsBlockElement(htmlChildName) || htmlChildName == "img" || htmlChildName == "br" || htmlChildName == "hr") { elementHasChildren = true; break; } } } string xamlElementName = elementHasChildren ? HtmlToXamlConverter.Xaml_Span : HtmlToXamlConverter.Xaml_Run; // Create currentProperties as a compilation of local and inheritedProperties, set localProperties IDictionary localProperties; IDictionary currentProperties = GetElementProperties(htmlElement, inheritedProperties, out localProperties, stylesheet, sourceContext); // Create a XAML element corresponding to this html element XmlElement xamlElement = xamlParentElement.OwnerDocument.CreateElementNS(_xamlNamespace,xamlElementName); ApplyLocalProperties(xamlElement, localProperties, /*isBlock:*/false); // Recurse into element subtree for (IXmlNode htmlChildNode = htmlElement.FirstChild; htmlChildNode != null; htmlChildNode = htmlChildNode.NextSibling) { AddInline(xamlElement, htmlChildNode, currentProperties, stylesheet, sourceContext); } // Add the new element to the parent. xamlParentElement.AppendChild(xamlElement); }
/// <summary> /// Generates Paragraph element from P, H1-H7, Center etc. /// </summary> /// <param name="xamlParentElement"> /// XmlElement representing Xaml parent to which the converted element should be added /// </param> /// <param name="htmlElement"> /// XmlElement representing Html element to be converted /// </param> /// <param name="inheritedProperties"> /// properties inherited from parent context /// </param> /// <param name="stylesheet"></param> /// <param name="sourceContext"></param> /// true indicates that a content added by this call contains at least one block element /// </param> private static void AddParagraph(XmlElement xamlParentElement, XmlElement htmlElement, IDictionary inheritedProperties, CssStylesheet stylesheet, List<XmlElement> sourceContext) { // Create currentProperties as a compilation of local and inheritedProperties, set localProperties IDictionary localProperties; IDictionary currentProperties = GetElementProperties(htmlElement, inheritedProperties, out localProperties, stylesheet, sourceContext); // Create a XAML element corresponding to this html element XmlElement xamlElement = xamlParentElement.OwnerDocument.CreateElementNS(_xamlNamespace, HtmlToXamlConverter.Xaml_Paragraph); ApplyLocalProperties(xamlElement, localProperties, /*isBlock:*/true); // Recurse into element subtree for (IXmlNode htmlChildNode = htmlElement.FirstChild; htmlChildNode != null; htmlChildNode = htmlChildNode.NextSibling) { AddInline(xamlElement, htmlChildNode, currentProperties, stylesheet, sourceContext); } // Add the new element to the parent. xamlParentElement.AppendChild(xamlElement); }
/// <summary> /// Converts htmlLIElement into Xaml ListItem element, and appends it to the parent xamlListElement /// </summary> /// <param name="xamlListElement"> /// XmlElement representing Xaml List element to which the converted td/th should be added /// </param> /// <param name="htmlLIElement"> /// XmlElement representing Html li element to be converted /// </param> /// <param name="inheritedProperties"> /// Properties inherited from parent context /// </param> private static void AddListItem(XmlElement xamlListElement, XmlElement htmlLIElement, IDictionary inheritedProperties, CssStylesheet stylesheet, List<XmlElement> sourceContext) { // Parameter validation Debug.Assert(xamlListElement != null); Debug.Assert(xamlListElement.LocalName.ToString() == Xaml_List); Debug.Assert(htmlLIElement != null); Debug.Assert(htmlLIElement.LocalName.ToLower() == "li"); Debug.Assert(inheritedProperties != null); IDictionary localProperties; IDictionary currentProperties = GetElementProperties(htmlLIElement, inheritedProperties, out localProperties, stylesheet, sourceContext); XmlElement xamlListItemElement = xamlListElement.OwnerDocument.CreateElementNS(_xamlNamespace,Xaml_ListItem); // TODO: process local properties for li element // Process children of the ListItem for (IXmlNode htmlChildNode = htmlLIElement.FirstChild; htmlChildNode != null; htmlChildNode = htmlChildNode != null ? htmlChildNode.NextSibling : null) { htmlChildNode = AddBlock(xamlListItemElement, htmlChildNode, currentProperties, stylesheet, sourceContext); } // Add resulting ListBoxItem to a xaml parent xamlListElement.AppendChild(xamlListItemElement); }
/// <summary> /// Converts htmlColElement into Xaml TableColumn element, and appends it to the parent /// xamlTableColumnGroupElement /// </summary> /// <param name="xamlTableElement"></param> /// <param name="htmlColElement"> /// XmlElement representing Html col element to be converted /// </param> /// <param name="inheritedProperties"> /// properties inherited from parent context /// </param> /// <param name="stylesheet"></param> /// <param name="sourceContext"></param> private static void AddTableColumn(XmlElement xamlTableElement, XmlElement htmlColElement, IDictionary inheritedProperties, CssStylesheet stylesheet, List<XmlElement> sourceContext) { IDictionary localProperties; IDictionary currentProperties = GetElementProperties(htmlColElement, inheritedProperties, out localProperties, stylesheet, sourceContext); XmlElement xamlTableColumnElement = xamlTableElement.OwnerDocument.CreateElementNS(_xamlNamespace,Xaml_TableColumn); // TODO: process local properties for TableColumn element // Col is an empty element, with no subtree xamlTableElement.AppendChild(xamlTableColumnElement); }
/// <summary> /// Adds TableCell elements to xamlTableRowElement. /// </summary> /// <param name="xamlTableRowElement"> /// XmlElement representing Xaml TableRow element to which the converted cells should be added /// </param> /// <param name="htmlTDStartNode"> /// XmlElement representing the child of tr or tbody element from which we should start adding td elements /// </param> /// <param name="currentProperties"> /// properties of the current html tr element to which cells are to be added /// </param> /// <returns> /// XmlElement representing the current position of the iterator among the children of the parent Html tbody/tr element /// </returns> private static IXmlNode AddTableCellsToTableRow(XmlElement xamlTableRowElement, IXmlNode htmlTDStartNode, IDictionary currentProperties, IList columnStarts, IList activeRowSpans, CssStylesheet stylesheet, List<XmlElement> sourceContext) { // parameter validation Debug.Assert(xamlTableRowElement.LocalName.ToString() == Xaml_TableRow); Debug.Assert(currentProperties != null); if (columnStarts != null) { Debug.Assert(activeRowSpans.Count == columnStarts.Count); } IXmlNode htmlChildNode = htmlTDStartNode; double columnStart = 0; double columnWidth = 0; int columnIndex = 0; int columnSpan = 0; while (htmlChildNode != null && htmlChildNode.LocalName.ToLower() != "tr" && htmlChildNode.LocalName.ToLower() != "tbody" && htmlChildNode.LocalName.ToLower() != "thead" && htmlChildNode.LocalName.ToLower() != "tfoot") { if (htmlChildNode.LocalName.ToLower() == "td" || htmlChildNode.LocalName.ToLower() == "th") { XmlElement xamlTableCellElement = xamlTableRowElement.OwnerDocument.CreateElementNS(_xamlNamespace, Xaml_TableCell); sourceContext.Add((XmlElement)htmlChildNode); IDictionary tdElementLocalProperties; IDictionary tdElementCurrentProperties = GetElementProperties((XmlElement)htmlChildNode, currentProperties, out tdElementLocalProperties, stylesheet, sourceContext); // TODO: determine if localProperties can be used instead of htmlChildNode in this call, and if they can, // make necessary changes and use them instead. ApplyPropertiesToTableCellElement((XmlElement)htmlChildNode, xamlTableCellElement); if (columnStarts != null) { Debug.Assert(columnIndex < columnStarts.Count - 1); while (columnIndex < activeRowSpans.Count && (int)activeRowSpans[columnIndex] > 0) { activeRowSpans[columnIndex] = (int)activeRowSpans[columnIndex] - 1; Debug.Assert((int)activeRowSpans[columnIndex] >= 0); columnIndex++; } Debug.Assert(columnIndex < columnStarts.Count - 1); columnStart = (double)columnStarts[columnIndex]; columnWidth = GetColumnWidth((XmlElement)htmlChildNode); columnSpan = CalculateColumnSpan(columnIndex, columnWidth, columnStarts); int rowSpan = GetRowSpan((XmlElement)htmlChildNode); // Column cannot have no span Debug.Assert(columnSpan > 0); Debug.Assert(columnIndex + columnSpan < columnStarts.Count); xamlTableCellElement.SetAttribute(Xaml_TableCell_ColumnSpan, columnSpan.ToString()); // Apply row span for (int spannedColumnIndex = columnIndex; spannedColumnIndex < columnIndex + columnSpan; spannedColumnIndex++) { Debug.Assert(spannedColumnIndex < activeRowSpans.Count); activeRowSpans[spannedColumnIndex] = (rowSpan - 1); Debug.Assert((int)activeRowSpans[spannedColumnIndex] >= 0); } columnIndex = columnIndex + columnSpan; } AddDataToTableCell(xamlTableCellElement, htmlChildNode.FirstChild, tdElementCurrentProperties, stylesheet, sourceContext); if (xamlTableCellElement.HasChildNodes()) { xamlTableRowElement.AppendChild(xamlTableCellElement); } Debug.Assert(sourceContext.Count > 0 && sourceContext[sourceContext.Count - 1] == htmlChildNode); sourceContext.RemoveAt(sourceContext.Count - 1); htmlChildNode = htmlChildNode.NextSibling; } else { // Not td element. Ignore it. // TODO: Consider better recovery htmlChildNode = htmlChildNode.NextSibling; } } return htmlChildNode; }
protected override void OnNavigatedTo(NavigationEventArgs e) { if (e != null && e.Parameter != null) { CurrentCode = e.Parameter as Code; if (CurrentCode != null) { Report = new XmlDocument(); CodeElement = Report.CreateElement("Code"); CodeElement.SetAttribute("CPRStartTime", CurrentCode.CPRStartTime.ToString()); CodeElement.SetAttribute("CPREndTime", CurrentCode.CPREndTime.ToString()); DefibElement = Report.CreateElement("Defibrillation"); PatientInfoElement = Report.CreateElement("PatientInformation"); CodeElement.AppendChild(DefibElement); CodeElement.AppendChild(PatientInfoElement); Report.AppendChild(CodeElement); } } if (CurrentDefibrillation == null) { CurrentDefibrillation = new Defibrillation(); } if (CurrentPatientInfo == null) { CurrentPatientInfo = new PatientInformation(); } base.OnNavigatedTo(e); }
/// <summary> /// Private utility method that adds text elements to a binding element. /// </summary> private static void AddSubTextElements(XmlElement bindingElement, string[] texts) { for (int i = 0; i < texts.Length; i++) { string text = texts[i]; if (!string.IsNullOrEmpty(text)) { XmlElement textElement = bindingElement.OwnerDocument.CreateElement("text"); textElement.SetAttribute("id", (i + 1).ToString()); textElement.InnerText = text; bindingElement.AppendChild(textElement); } } }
public void AddCategory(BlogPostCategory category) { XmlElement catEl = _atomVer.CreateCategoryElement(_entryNode.OwnerDocument, category.Id, _categoryScheme, category.Name); _entryNode.AppendChild(catEl); }
/// <summary> /// Take the blog post data and put it into the XML node. /// </summary> protected virtual void Populate(BlogPost post, Uri documentUri, XmlElement node, bool publish) { AtomEntry atomEntry = new AtomEntry(_atomVer, _atomNS, CategoryScheme, _nsMgr, documentUri, node); if (post.IsNew) { atomEntry.GenerateId(); } atomEntry.Title = post.Title; if (Options.SupportsExcerpt && post.Excerpt != null && post.Excerpt.Length > 0) { atomEntry.Excerpt = post.Excerpt; } // extra space is to work around AOL Journals XML parsing bug atomEntry.ContentHtml = post.Contents + " "; if (Options.SupportsCustomDate && post.HasDatePublishedOverride) { atomEntry.PublishDate = post.DatePublishedOverride; } if (Options.SupportsCategories) { atomEntry.ClearCategories(); foreach (BlogPostCategory cat in post.Categories) { if (!BlogPostCategoryNone.IsCategoryNone(cat)) { atomEntry.AddCategory(cat); } } if (Options.SupportsNewCategories) { foreach (BlogPostCategory cat in post.NewCategories) { if (!BlogPostCategoryNone.IsCategoryNone(cat)) { atomEntry.AddCategory(cat); } } } } if (Options.SupportsPostAsDraft) { // remove existing draft nodes while (true) { var draftNode = node.SelectSingleNodeNS(@"app:control/app:draft", _nsMgr.ToNSMethodFormat()); if (draftNode == null) { break; } draftNode.ParentNode.RemoveChild(draftNode); } if (!publish) { // ensure control node exists var controlNode = node.SelectSingleNodeNS(@"app:control", _nsMgr.ToNSMethodFormat()); if (controlNode == null) { controlNode = node.OwnerDocument.CreateElementNS(_pubNS.Uri, _pubNS.Prefix + ":control"); node.AppendChild(controlNode); } // create new draft node XmlElement newDraftNode = node.OwnerDocument.CreateElementNS(_pubNS.Uri, _pubNS.Prefix + ":draft"); newDraftNode.InnerText = "yes"; controlNode.AppendChild(newDraftNode); } } //post.Categories; //post.CommentPolicy; //post.CopyFrom; //post.Excerpt; //post.HasDatePublishedOverride; //post.Id; //post.IsNew; //post.IsTemporary; //post.Keywords; //post.Link; //post.Permalink; //post.PingUrls; //post.ResetToNewPost; //post.TrackbackPolicy; }
/// <summary> /// Creates a Paragraph element and adds all nodes starting from htmlNode /// converted to appropriate Inlines. /// </summary> /// <param name="xamlParentElement"> /// XmlElement representing Xaml parent to which the converted element should be added /// </param> /// <param name="htmlNode"> /// XmlNode starting a collection of implicitly wrapped inlines. /// </param> /// <param name="inheritedProperties"> /// properties inherited from parent context /// </param> /// <param name="stylesheet"></param> /// <param name="sourceContext"></param> /// true indicates that a content added by this call contains at least one block element /// </param> /// <returns> /// The last htmlNode added to the implicit paragraph /// </returns> private static IXmlNode AddImplicitParagraph(XmlElement xamlParentElement, IXmlNode htmlNode, IDictionary inheritedProperties, CssStylesheet stylesheet, List<XmlElement> sourceContext) { // Collect all non-block elements and wrap them into implicit Paragraph XmlElement xamlParagraph = xamlParentElement.OwnerDocument.CreateElementNS(_xamlNamespace,HtmlToXamlConverter.Xaml_Paragraph); IXmlNode lastNodeProcessed = null; while (htmlNode != null) { if (htmlNode is XmlComment) { DefineInlineFragmentParent((XmlComment)htmlNode, /*xamlParentElement:*/null); } else if (htmlNode is XmlText) { if (htmlNode.NodeValue.ToString().Trim().Length > 0) { AddTextRun(xamlParagraph, htmlNode.NodeValue.ToString()); } } else if (htmlNode is XmlElement) { string htmlChildName = ((XmlElement)htmlNode).LocalName.ToLower(); if (HtmlSchema.IsBlockElement(htmlChildName)) { // The sequence of non-blocked inlines ended. Stop implicit loop here. break; } else { AddInline(xamlParagraph, (XmlElement)htmlNode, inheritedProperties, stylesheet, sourceContext); } } // Store last processed node to return it at the end lastNodeProcessed = htmlNode; htmlNode = htmlNode.NextSibling; } // Add the Paragraph to the parent // If only whitespaces and commens have been encountered, // then we have nothing to add in implicit paragraph; forget it. if (xamlParagraph.FirstChild != null) { xamlParentElement.AppendChild(xamlParagraph); } // Need to return last processed node return lastNodeProcessed; }
/// <summary> /// Adds TableRow elements to xamlTableBodyElement. The rows are converted from Html tr elements that /// may be the children of an Html tbody element or an Html table element with tbody missing /// </summary> /// <param name="xamlTableBodyElement"> /// XmlElement representing Xaml TableRowGroup element to which the converted rows should be added /// </param> /// <param name="htmlTRStartNode"> /// XmlElement representing the first tr child of the tbody element to be read /// </param> /// <param name="currentProperties"> /// Hashtable representing current properties of the tbody element that are generated and applied in the /// AddTable function; to be used as inheritedProperties when adding tr elements /// </param> /// <param name="columnStarts"></param> /// <param name="stylesheet"></param> /// <param name="sourceContext"></param> /// <returns> /// XmlNode representing the current position of the iterator among tr elements /// </returns> private static IXmlNode AddTableRowsToTableBody(XmlElement xamlTableBodyElement, IXmlNode htmlTRStartNode, IDictionary currentProperties, IList columnStarts, CssStylesheet stylesheet, List<XmlElement> sourceContext) { // Parameter validation Debug.Assert(xamlTableBodyElement.LocalName.ToString() == Xaml_TableRowGroup); Debug.Assert(currentProperties != null); // Initialize child node for iteratimg through children to the first tr element IXmlNode htmlChildNode = htmlTRStartNode; List<int> activeRowSpans = null; if (columnStarts != null) { activeRowSpans = new List<int>(); InitializeActiveRowSpans(activeRowSpans, columnStarts.Count); } while (htmlChildNode != null && htmlChildNode.LocalName.ToLower() != "tbody") { if (htmlChildNode.LocalName.ToLower() == "tr") { XmlElement xamlTableRowElement = xamlTableBodyElement.OwnerDocument.CreateElementNS(_xamlNamespace, Xaml_TableRow); sourceContext.Add((XmlElement)htmlChildNode); // Get tr element properties IDictionary trElementLocalProperties; IDictionary trElementCurrentProperties = GetElementProperties((XmlElement)htmlChildNode, currentProperties, out trElementLocalProperties, stylesheet, sourceContext); // TODO: apply local properties to tr element AddTableCellsToTableRow(xamlTableRowElement, htmlChildNode.FirstChild, trElementCurrentProperties, columnStarts, activeRowSpans, stylesheet, sourceContext); if (xamlTableRowElement.HasChildNodes()) { xamlTableBodyElement.AppendChild(xamlTableRowElement); } Debug.Assert(sourceContext.Count > 0 && sourceContext[sourceContext.Count - 1] == htmlChildNode); sourceContext.RemoveAt(sourceContext.Count - 1); // Advance htmlChildNode = htmlChildNode.NextSibling; } else if (htmlChildNode.LocalName.ToLower() == "td") { // Tr element is not present. We create one and add td elements to it XmlElement xamlTableRowElement = xamlTableBodyElement.OwnerDocument.CreateElementNS(_xamlNamespace, Xaml_TableRow); // This is incorrect formatting and the column starts should not be set in this case Debug.Assert(columnStarts == null); htmlChildNode = AddTableCellsToTableRow(xamlTableRowElement, htmlChildNode, currentProperties, columnStarts, activeRowSpans, stylesheet, sourceContext); if (xamlTableRowElement.HasChildNodes()) { xamlTableBodyElement.AppendChild(xamlTableRowElement); } } else { // Not a tr or td element. Ignore it. // TODO: consider better recovery here htmlChildNode = htmlChildNode.NextSibling; } } return htmlChildNode; }
// ............................................................. // // Lists // // ............................................................. /// <summary> /// Converts Html ul or ol element into Xaml list element. During conversion if the ul/ol element has any children /// that are not li elements, they are ignored and not added to the list element /// </summary> /// <param name="xamlParentElement"> /// XmlElement representing Xaml parent to which the converted element should be added /// </param> /// <param name="htmlListElement"> /// XmlElement representing Html ul/ol element to be converted /// </param> /// <param name="inheritedProperties"> /// properties inherited from parent context /// </param> /// <param name="stylesheet"></param> /// <param name="sourceContext"></param> private static void AddList(XmlElement xamlParentElement, XmlElement htmlListElement, IDictionary inheritedProperties, CssStylesheet stylesheet, List<XmlElement> sourceContext) { string htmlListElementName = htmlListElement.LocalName.ToLower(); IDictionary localProperties; IDictionary currentProperties = GetElementProperties(htmlListElement, inheritedProperties, out localProperties, stylesheet, sourceContext); // Create Xaml List element XmlElement xamlListElement = xamlParentElement.OwnerDocument.CreateElementNS(_xamlNamespace, Xaml_List); // Set default list markers if (htmlListElementName == "ol") { // Ordered list xamlListElement.SetAttribute(HtmlToXamlConverter.Xaml_List_MarkerStyle, Xaml_List_MarkerStyle_Decimal); } else { // Unordered list - all elements other than OL treated as unordered lists xamlListElement.SetAttribute(HtmlToXamlConverter.Xaml_List_MarkerStyle, Xaml_List_MarkerStyle_Disc); } // Apply local properties to list to set marker attribute if specified // TODO: Should we have separate list attribute processing function? ApplyLocalProperties(xamlListElement, localProperties, /*isBlock:*/true); // Recurse into list subtree for (IXmlNode htmlChildNode = htmlListElement.FirstChild; htmlChildNode != null; htmlChildNode = htmlChildNode.NextSibling) { if (htmlChildNode is XmlElement && htmlChildNode.LocalName.ToLower() == "li") { sourceContext.Add((XmlElement)htmlChildNode); AddListItem(xamlListElement, (XmlElement)htmlChildNode, currentProperties, stylesheet, sourceContext); Debug.Assert(sourceContext.Count > 0 && sourceContext[sourceContext.Count - 1] == htmlChildNode); sourceContext.RemoveAt(sourceContext.Count - 1); } else { // Not an li element. Add it to previous ListBoxItem // We need to append the content to the end // of a previous list item. } } // Add the List element to xaml tree - if it is not empty if (xamlListElement.HasChildNodes()) { xamlParentElement.AppendChild(xamlListElement); } }
// Adds a text run to a xaml tree private static void AddTextRun(XmlElement xamlElement, string textData) { // Remove control characters for (int i = 0; i < textData.Length; i++) { if (Char.IsControl(textData[i])) { textData = textData.Remove(i--, 1); // decrement i to compensate for character removal } } // Replace No-Breaks by spaces (160 is a code of entity in html) // This is a work around the bug in Avalon which does not render nbsp. textData = textData.Replace((char)160, ' '); if (textData.Length > 0) { xamlElement.AppendChild(xamlElement.OwnerDocument.CreateTextNode(textData)); } }
/// <summary> /// If li items are found without a parent ul/ol element in Html string, creates xamlListElement as their parent and adds /// them to it. If the previously added node to the same xamlParentElement was a List, adds the elements to that list. /// Otherwise, we create a new xamlListElement and add them to it. Elements are added as long as li elements appear sequentially. /// The first non-li or text node stops the addition. /// </summary> /// <param name="xamlParentElement"> /// Parent element for the list /// </param> /// <param name="htmlLIElement"> /// Start Html li element without parent list /// </param> /// <param name="inheritedProperties"> /// Properties inherited from parent context /// </param> /// <returns> /// XmlNode representing the first non-li node in the input after one or more li's have been processed. /// </returns> private static XmlElement AddOrphanListItems(XmlElement xamlParentElement, XmlElement htmlLIElement, IDictionary inheritedProperties, CssStylesheet stylesheet, List<XmlElement> sourceContext) { Debug.Assert(htmlLIElement.LocalName.ToLower() == "li"); XmlElement lastProcessedListItemElement = null; // Find out the last element attached to the xamlParentElement, which is the previous sibling of this node IXmlNode xamlListItemElementPreviousSibling = xamlParentElement.LastChild; XmlElement xamlListElement; if (xamlListItemElementPreviousSibling != null && xamlListItemElementPreviousSibling.LocalName.ToString() == Xaml_List) { // Previously added Xaml element was a list. We will add the new li to it xamlListElement = (XmlElement)xamlListItemElementPreviousSibling; } else { // No list element near. Create our own. xamlListElement = xamlParentElement.OwnerDocument.CreateElementNS( _xamlNamespace,Xaml_List); xamlParentElement.AppendChild(xamlListElement); } IXmlNode htmlChildNode = htmlLIElement; string htmlChildNodeName = htmlChildNode == null ? null : htmlChildNode.LocalName.ToLower(); // Current element properties missed here. //currentProperties = GetElementProperties(htmlLIElement, inheritedProperties, out localProperties, stylesheet); // Add li elements to the parent xamlListElement we created as long as they appear sequentially // Use properties inherited from xamlParentElement for context while (htmlChildNode != null && htmlChildNodeName == "li") { AddListItem(xamlListElement, (XmlElement)htmlChildNode, inheritedProperties, stylesheet, sourceContext); lastProcessedListItemElement = (XmlElement)htmlChildNode; htmlChildNode = htmlChildNode.NextSibling; htmlChildNodeName = htmlChildNode == null ? null : htmlChildNode.LocalName.ToLower(); } return lastProcessedListItemElement; }
// Extracts a content of an element stored as InlineFragmentParentElement // into a separate Span wrapper. // Note: when selected content does not cross paragraph boundaries, // the fragment is marked within private static XmlElement ExtractInlineFragment(XmlElement xamlFlowDocumentElement) { if (InlineFragmentParentElement != null) { if (InlineFragmentParentElement.LocalName.ToString() == HtmlToXamlConverter.Xaml_Span) { xamlFlowDocumentElement = InlineFragmentParentElement; } else { xamlFlowDocumentElement = xamlFlowDocumentElement.OwnerDocument.CreateElementNS( _xamlNamespace,HtmlToXamlConverter.Xaml_Span); while (InlineFragmentParentElement.FirstChild != null) { IXmlNode copyNode = InlineFragmentParentElement.FirstChild; InlineFragmentParentElement.RemoveChild(copyNode); xamlFlowDocumentElement.AppendChild(copyNode); } } } return xamlFlowDocumentElement; }
// ............................................................. // // Text Flow Elements // // ............................................................. /// <summary> /// Generates Section or Paragraph element from DIV depending whether it contains any block elements or not /// </summary> /// <param name="xamlParentElement"> /// XmlElement representing Xaml parent to which the converted element should be added /// </param> /// <param name="htmlElement"> /// XmlElement representing Html element to be converted /// </param> /// <param name="inheritedProperties"> /// properties inherited from parent context /// </param> /// <param name="stylesheet"></param> /// <param name="sourceContext"></param> /// true indicates that a content added by this call contains at least one block element /// </param> private static void AddSection(XmlElement xamlParentElement, XmlElement htmlElement, IDictionary inheritedProperties, CssStylesheet stylesheet, List<XmlElement> sourceContext) { // Analyze the content of htmlElement to decide what xaml element to choose - Section or Paragraph. // If this Div has at least one block child then we need to use Section, otherwise use Paragraph bool htmlElementContainsBlocks = false; for (IXmlNode htmlChildNode = htmlElement.FirstChild; htmlChildNode != null; htmlChildNode = htmlChildNode.NextSibling) { if (htmlChildNode is XmlElement) { string htmlChildName = ((XmlElement)htmlChildNode).LocalName.ToLower(); if (HtmlSchema.IsBlockElement(htmlChildName)) { htmlElementContainsBlocks = true; break; } } } if (!htmlElementContainsBlocks) { // The Div does not contain any block elements, so we can treat it as a Paragraph AddParagraph(xamlParentElement, htmlElement, inheritedProperties, stylesheet, sourceContext); } else { // The Div has some nested blocks, so we treat it as a Section // Create currentProperties as a compilation of local and inheritedProperties, set localProperties IDictionary localProperties; IDictionary currentProperties = GetElementProperties(htmlElement, inheritedProperties, out localProperties, stylesheet, sourceContext); // Create a XAML element corresponding to this html element XmlElement xamlElement = xamlParentElement.OwnerDocument.CreateElementNS(_xamlNamespace,HtmlToXamlConverter.Xaml_Section); ApplyLocalProperties(xamlElement, localProperties, /*isBlock:*/true); // Decide whether we can unwrap this element as not having any formatting significance. if (xamlElement.Attributes==null) { // This elements is a group of block elements whitout any additional formatting. // We can add blocks directly to xamlParentElement and avoid // creating unnecessary Sections nesting. xamlElement = xamlParentElement; } // Recurse into element subtree for (IXmlNode htmlChildNode = htmlElement.FirstChild; htmlChildNode != null; htmlChildNode = htmlChildNode != null ? htmlChildNode.NextSibling : null) { htmlChildNode = AddBlock(xamlElement, htmlChildNode, currentProperties, stylesheet, sourceContext); } // Add the new element to the parent. if (xamlElement != xamlParentElement) { xamlParentElement.AppendChild(xamlElement); } } }
// ............................................................. // // Line Breaks // // ............................................................. private static void AddBreak(XmlElement xamlParentElement, string htmlElementName) { // Create new xaml element corresponding to this html element XmlElement xamlLineBreak = xamlParentElement.OwnerDocument.CreateElementNS(_xamlNamespace,HtmlToXamlConverter.Xaml_LineBreak); xamlParentElement.AppendChild(xamlLineBreak); if (htmlElementName == "hr") { XmlText xamlHorizontalLine = xamlParentElement.OwnerDocument.CreateTextNode("----------------------"); xamlParentElement.AppendChild(xamlHorizontalLine); xamlLineBreak = xamlParentElement.OwnerDocument.CreateElementNS(_xamlNamespace, HtmlToXamlConverter.Xaml_LineBreak); xamlParentElement.AppendChild(xamlLineBreak); } }
// ............................................................. // // Tables // // ............................................................. /// <summary> /// Converts htmlTableElement to a Xaml Table element. Adds tbody elements if they are missing so /// that a resulting Xaml Table element is properly formed. /// </summary> /// <param name="xamlParentElement"> /// Parent xaml element to which a converted table must be added. /// </param> /// <param name="htmlTableElement"> /// XmlElement reprsenting the Html table element to be converted /// </param> /// <param name="inheritedProperties"> /// Hashtable representing properties inherited from parent context. /// </param> private static void AddTable(XmlElement xamlParentElement, XmlElement htmlTableElement, IDictionary inheritedProperties, CssStylesheet stylesheet, List<XmlElement> sourceContext) { // Parameter validation Debug.Assert(htmlTableElement.LocalName.ToLower() == "table"); Debug.Assert(xamlParentElement != null); Debug.Assert(inheritedProperties != null); // Create current properties to be used by children as inherited properties, set local properties IDictionary localProperties; IDictionary currentProperties = GetElementProperties(htmlTableElement, inheritedProperties, out localProperties, stylesheet, sourceContext); // TODO: process localProperties for tables to override defaults, decide cell spacing defaults // Check if the table contains only one cell - we want to take only its content XmlElement singleCell = GetCellFromSingleCellTable(htmlTableElement); if (singleCell != null) { // Need to push skipped table elements onto sourceContext sourceContext.Add(singleCell); // Add the cell's content directly to parent for (IXmlNode htmlChildNode = singleCell.FirstChild; htmlChildNode != null; htmlChildNode = htmlChildNode != null ? htmlChildNode.NextSibling : null) { htmlChildNode = AddBlock(xamlParentElement, htmlChildNode, currentProperties, stylesheet, sourceContext); } Debug.Assert(sourceContext.Count > 0 && sourceContext[sourceContext.Count - 1] == singleCell); sourceContext.RemoveAt(sourceContext.Count - 1); } else { // Create xamlTableElement XmlElement xamlTableElement = xamlParentElement.OwnerDocument.CreateElementNS(_xamlNamespace,Xaml_Table); // Analyze table structure for column widths and rowspan attributes IList columnStarts = AnalyzeTableStructure(htmlTableElement, stylesheet); // Process COLGROUP & COL elements AddColumnInformation(htmlTableElement, xamlTableElement, columnStarts, currentProperties, stylesheet, sourceContext); // Process table body - TBODY and TR elements IXmlNode htmlChildNode = htmlTableElement.FirstChild; while (htmlChildNode != null) { string htmlChildName = htmlChildNode.LocalName.ToLower(); // Process the element if (htmlChildName == "tbody" || htmlChildName == "thead" || htmlChildName == "tfoot") { // Add more special processing for TableHeader and TableFooter XmlElement xamlTableBodyElement = xamlTableElement.OwnerDocument.CreateElementNS(_xamlNamespace,Xaml_TableRowGroup); xamlTableElement.AppendChild(xamlTableBodyElement); sourceContext.Add((XmlElement)htmlChildNode); // Get properties of Html tbody element IDictionary tbodyElementLocalProperties; IDictionary tbodyElementCurrentProperties = GetElementProperties((XmlElement)htmlChildNode, currentProperties, out tbodyElementLocalProperties, stylesheet, sourceContext); // TODO: apply local properties for tbody // Process children of htmlChildNode, which is tbody, for tr elements AddTableRowsToTableBody(xamlTableBodyElement, htmlChildNode.FirstChild, tbodyElementCurrentProperties, columnStarts, stylesheet, sourceContext); if (xamlTableBodyElement.HasChildNodes()) { xamlTableElement.AppendChild(xamlTableBodyElement); // else: if there is no TRs in this TBody, we simply ignore it } Debug.Assert(sourceContext.Count > 0 && sourceContext[sourceContext.Count - 1] == htmlChildNode); sourceContext.RemoveAt(sourceContext.Count - 1); htmlChildNode = htmlChildNode.NextSibling; } else if (htmlChildName == "tr") { // Tbody is not present, but tr element is present. Tr is wrapped in tbody XmlElement xamlTableBodyElement = xamlTableElement.OwnerDocument.CreateElementNS(_xamlNamespace,Xaml_TableRowGroup); // We use currentProperties of xamlTableElement when adding rows since the tbody element is artificially created and has // no properties of its own htmlChildNode = AddTableRowsToTableBody(xamlTableBodyElement, htmlChildNode, currentProperties, columnStarts, stylesheet, sourceContext); if (xamlTableBodyElement.HasChildNodes()) { xamlTableElement.AppendChild(xamlTableBodyElement); } } else { // Element is not tbody or tr. Ignore it. // TODO: add processing for thead, tfoot elements and recovery for td elements htmlChildNode = htmlChildNode.NextSibling; } } if (xamlTableElement.HasChildNodes()) { xamlParentElement.AppendChild(xamlTableElement); } } }
private async void nextButton_Click_1(object sender, RoutedEventArgs e) { if ("Exit".Equals(nextButton.Content.ToString())) { StorageFile st = null; bool exists = true; XmlNodeList _names = null, _scores = null; try { st = await ApplicationData.Current.LocalFolder.GetFileAsync("score.xml"); dom = await XmlDocument.LoadFromFileAsync(st); _names = dom.GetElementsByTagName("name"); _scores = dom.GetElementsByTagName("highscore"); } catch (Exception) { exists = false; } if (!exists) { st = await ApplicationData.Current.LocalFolder.CreateFileAsync("score.xml"); } ObservableCollection<Player> playerTable = new ObservableCollection<Player>(); if (_names != null) { for (int i = 0; i < _names.Count; i++) { string tempName = _names.ElementAt(i).InnerText; int tempScore = Int32.Parse(_scores.ElementAt(i).InnerText); playerTable.Add(new Player(tempName, tempScore)); } } playerTable.Add(new Player(playerName, score)); dom = new XmlDocument(); x = dom.CreateElement("users"); dom.AppendChild(x); foreach (var elem in playerTable) { XmlElement x1 = dom.CreateElement("user"); XmlElement x11 = dom.CreateElement("name"); x11.InnerText = elem.Name; x1.AppendChild(x11); XmlElement x12 = dom.CreateElement("highscore"); x12.InnerText = elem.Score.ToString(); x1.AppendChild(x12); x.AppendChild(x1); } await dom.SaveToFileAsync(st); Frame.Navigate(typeof(MainPage)); } else { var param = new Parameters(); param.Score = this.score + 10 + this.levelCount; param.Name = this.playerName; param.Level = this.levelCount + 1; param.Counter = this.futureCounter; Frame.Navigate(typeof(Level), param); } }