XmlDiffViewElement.cs
上传用户:hbhltzc
上传日期:2022-06-04
资源大小:1925k
文件大小:38k
源码类别:

xml/soap/webservice

开发平台:

Visual C++

  1. //  ---------------------------------------------------------------------------
  2. // <copyright company="Microsoft Corporation" file="XmlDiffViewElement.cs">
  3. //     Copyright (c) Microsoft Corporation 2005
  4. // </copyright>
  5. // <project>
  6. //     XmlDiffView
  7. // </project>
  8. // <summary>
  9. //     Summary description for this file
  10. // </summary>           
  11. // <history>
  12. //      [barryw] 03MAR05 Created
  13. // </history>
  14. //  ---------------------------------------------------------------------------
  15. namespace Microsoft.XmlDiffPatch
  16. {
  17.     using System;
  18.     using System.IO;
  19.     using System.Xml;
  20.     using System.Diagnostics;
  21.     /// <summary>
  22.     /// Class to generate output for xml elements.
  23.     /// </summary>
  24.     internal class XmlDiffViewElement : XmlDiffViewParentNode
  25.     {
  26.         #region Member variables section
  27.         // name
  28.         private string localName;
  29.         private string prefix;
  30.         private string namespaceUri;
  31.         private string name;
  32.         // attributes
  33.         private XmlDiffViewAttribute attributes;
  34.         private bool ignorePrefixes;
  35.         #endregion
  36.         
  37.         #region  Constructors section
  38.         /// <summary>
  39.         /// Constructor.
  40.         /// </summary>
  41.         /// <param name="localName">Element node name</param>
  42.         /// <param name="prefix">xml node prefix</param>
  43.         /// <param name="namespaceUri">Uniform Resource Identifier (URI)
  44.         /// </param>
  45.         /// <param name="ignorePrefix">Ignore differences in the prefix</param>
  46.         public XmlDiffViewElement(
  47.             string localName, 
  48.             string prefix, 
  49.             string namespaceUri, 
  50.             bool ignorePrefix) : 
  51.             base(XmlNodeType.Element)
  52.         {
  53.             this.LocalName = localName;
  54.             this.Prefix = prefix;
  55.             this.NamespaceUri = namespaceUri;
  56.             if (this.Prefix != string.Empty)
  57.             {
  58.                 this.Name = this.Prefix + ":" + this.LocalName;
  59.             }
  60.             else
  61.             {
  62.                     this.Name = this.LocalName;
  63.             }
  64.             this.ignorePrefixes = ignorePrefix;
  65.         }
  66.         #endregion
  67.         #region Properties section
  68.         /// <summary>
  69.         /// Gets or sets an attributes object.
  70.         /// </summary>
  71.         public XmlDiffViewAttribute Attributes
  72.         {
  73.             get
  74.             {
  75.                 return this.attributes;
  76.             }
  77.             set
  78.             {
  79.                 this.attributes = value;
  80.             }
  81.         }
  82.         /// <summary>
  83.         /// Returns and exception("OuterXml is not 
  84.         /// supported on XmlDiffViewElement.
  85.         /// </summary>
  86.         public override string OuterXml
  87.         {
  88.             get
  89.             {
  90.                 string message = "OuterXml is not supported" +
  91.                     " on XmlDiffViewElement.";
  92.                 throw new Exception(message);
  93.             }
  94.         }
  95.         /// <summary>
  96.         /// Gets or sets the name of the element without the prefix.
  97.         /// </summary>
  98.         public string LocalName
  99.         {
  100.             get
  101.             {
  102.                 return this.localName;
  103.             }
  104.             set
  105.             {
  106.                 this.localName = value;
  107.             }
  108.         }
  109.         /// <summary>
  110.         /// Gets or sets the prefix.
  111.         /// </summary>
  112.         public string Prefix
  113.         {
  114.             get
  115.             {
  116.                 return this.prefix;
  117.             }
  118.             set
  119.             {
  120.                 this.prefix = value;
  121.             }
  122.         }
  123.         /// <summary>
  124.         /// Gets or sets the namespace Uniform Resource Identifier (URI)
  125.         /// </summary>
  126.         public string NamespaceUri
  127.         {
  128.             get
  129.             {
  130.                 return this.namespaceUri;
  131.             }
  132.             set
  133.             {
  134.                 this.namespaceUri = value;
  135.             }
  136.         }
  137.         /// <summary>
  138.         /// Gets or set the name of the element with the prefix.
  139.         /// </summary>
  140.         public string Name
  141.         {
  142.             get
  143.             {
  144.                 return this.name;
  145.             }
  146.             set
  147.             {
  148.                 this.name = value;
  149.             }
  150.         }
  151.         #endregion
  152.         
  153.         #region Methods section
  154.         
  155.         /// <summary>
  156.         /// Gets an attribute object for the specified attribute name.
  157.         /// </summary>
  158.         /// <param name="name">attribute name</param>
  159.         /// <returns>an attribute object</returns>
  160.         public XmlDiffViewAttribute GetAttribute(string name)
  161.         {
  162.             XmlDiffViewAttribute curAttr = this.Attributes;
  163.             while (curAttr != null)
  164.             {
  165.                 if (curAttr.Name == name && 
  166.                     curAttr.Operation == XmlDiffViewOperation.Match)
  167.                 {
  168.                     return curAttr;
  169.                 }
  170.                 curAttr = (XmlDiffViewAttribute)curAttr.NextSibbling;
  171.             }
  172.             return null;
  173.         }
  174.         /// <summary>
  175.         /// Inserts an attribute object after the specified attribute object.
  176.         /// </summary>
  177.         /// <param name="newAttr">the attribute object to insert</param>
  178.         /// <param name="refAttr">attribute object to insert after</param>
  179.         public void InsertAttributeAfter(
  180.             XmlDiffViewAttribute newAttr, 
  181.             XmlDiffViewAttribute refAttr)
  182.         {
  183.             Debug.Assert(newAttr != null);
  184.             if (refAttr == null)
  185.             {
  186.                 newAttr.NextSibbling = this.Attributes;
  187.                 this.Attributes = newAttr;
  188.             }
  189.             else
  190.             {
  191.                 newAttr.NextSibbling = refAttr.NextSibbling;
  192.                 refAttr.NextSibbling = newAttr;
  193.             }
  194.             newAttr.Parent = this;
  195.         }
  196.         /// <summary>
  197.         /// Creates a complete copy of the current node.
  198.         /// </summary>
  199.         /// <param name="deep">has child nodes</param>
  200.         /// <returns>A copy of the current node</returns>
  201.         internal override XmlDiffViewNode Clone(bool deep)
  202.         {
  203.             XmlDiffViewElement newElement = new XmlDiffViewElement(
  204.                 this.LocalName, 
  205.                 this.Prefix, 
  206.                 this.NamespaceUri, 
  207.                 this.ignorePrefixes);
  208.             // attributes
  209.             {
  210.                 XmlDiffViewAttribute curAttr = this.Attributes;
  211.                 XmlDiffViewAttribute lastNewAtt = null;
  212.                 while (curAttr != null)
  213.                 {
  214.                     XmlDiffViewAttribute newAttr = 
  215.                         (XmlDiffViewAttribute)curAttr.Clone(true);
  216.                     newElement.InsertAttributeAfter(newAttr, lastNewAtt);
  217.                     lastNewAtt = newAttr;
  218.                     curAttr = (XmlDiffViewAttribute)curAttr.NextSibbling;
  219.                 }
  220.             }
  221.             if (!deep)
  222.             {
  223.                 return newElement;
  224.             }
  225.             // child nodes
  226.             {
  227.                 XmlDiffViewNode curChild = ChildNodes;
  228.                 XmlDiffViewNode lastNewChild = null;
  229.                 while (curChild != null)
  230.                 {
  231.                     XmlDiffViewNode newChild = curChild.Clone(true);
  232.                     newElement.InsertChildAfter(newChild, lastNewChild, false);
  233.                     lastNewChild = newChild;
  234.                     curChild = curChild.NextSibbling;
  235.                 }
  236.             }
  237.             return newElement;
  238.         }
  239.         /// <summary>
  240.         /// Generates  output data in html form
  241.         /// </summary>
  242.         /// <param name="writer">output stream</param>
  243.         /// <param name="indent">number of indentations</param>
  244.         internal override void DrawHtml(XmlWriter writer, int indent)
  245.         {
  246.             XmlDiffViewOperation typeOfDifference = Operation;
  247.             bool closeElement = false;
  248.             XmlDiffView.HtmlStartRow(writer);
  249.             this.DrawLinkNode(writer);
  250.             
  251.             for (int i = 0; i < 2; i++)
  252.             {
  253.                 XmlDiffView.HtmlStartCell(writer, indent);
  254.                 if (XmlDiffView.HtmlWriteToPane[(int)Operation, i])
  255.                 {
  256.                     closeElement = OutputNavigationHtml(writer);
  257.                     if (Operation == XmlDiffViewOperation.Change)
  258.                     {
  259.                         typeOfDifference = XmlDiffViewOperation.Match;
  260.                         XmlDiffView.HtmlWriteString(
  261.                             writer, 
  262.                             typeOfDifference, 
  263.                             Tags.XmlOpenBegin);
  264.                         if (i == 0)
  265.                         {
  266.                             this.DrawHtmlNameChange(
  267.                                 writer, 
  268.                                 this.LocalName, 
  269.                                 this.Prefix);
  270.                         }
  271.                         else
  272.                         {
  273.                             this.DrawHtmlNameChange(
  274.                                 writer, 
  275.                                 ChangeInformation.LocalName, 
  276.                                 ChangeInformation.Prefix);
  277.                         }
  278.                     }
  279.                     else
  280.                     {
  281.                         this.DrawHtmlName(
  282.                             writer, 
  283.                             typeOfDifference, 
  284.                             Tags.XmlOpenBegin, 
  285.                             string.Empty);
  286.                     }
  287.     
  288.                     if (closeElement)
  289.                     {
  290.                         // write the closing '</A>' tag.
  291.                         writer.WriteEndElement();
  292.                         closeElement = false;
  293.                     }
  294.                     // attributes
  295.                     this.DrawHtmlAttributes(writer, i);
  296.                     // close start tag
  297.                     if (ChildNodes != null)
  298.                     {
  299.                         XmlDiffView.HtmlWriteString(
  300.                             writer, 
  301.                             typeOfDifference, 
  302.                             Tags.XmlOpenEnd);
  303.                     }
  304.                     else
  305.                     {
  306.                         XmlDiffView.HtmlWriteString(
  307.                             writer, 
  308.                             typeOfDifference, 
  309.                             Tags.XmlOpenEndTerse);
  310.                     }
  311.                 }
  312.                 else
  313.                 {
  314.                     XmlDiffView.HtmlWriteEmptyString(writer);
  315.                 }
  316.                 XmlDiffView.HtmlEndCell(writer);
  317.             }
  318.             XmlDiffView.HtmlEndRow(writer);
  319.             // child nodes
  320.             if (ChildNodes != null)
  321.             {
  322.                 HtmlDrawChildNodes(writer, indent + XmlDiffView.DeltaIndent);
  323.                 // end element
  324.                 XmlDiffView.HtmlStartRow(writer);
  325.                 this.DrawLinkNode(writer);
  326.                 for (int i = 0; i < 2; i++)
  327.                 {
  328.                     XmlDiffView.HtmlStartCell(writer, indent);
  329.                     if (XmlDiffView.HtmlWriteToPane[(int)Operation, i])
  330.                     {
  331.                         if (Operation == XmlDiffViewOperation.Change)
  332.                         {
  333.                             Debug.Assert(typeOfDifference == 
  334.                                 XmlDiffViewOperation.Match);
  335.                             XmlDiffView.HtmlWriteString(
  336.                                 writer, 
  337.                                 typeOfDifference, 
  338.                                 Tags.XmlCloseBegin);
  339.                             if (i == 0)
  340.                             {
  341.                                 this.DrawHtmlNameChange(
  342.                                     writer, 
  343.                                     this.LocalName, 
  344.                                     this.Prefix);
  345.                             }
  346.                             else
  347.                             {
  348.                                 this.DrawHtmlNameChange(
  349.                                     writer, 
  350.                                     ChangeInformation.LocalName, 
  351.                                     ChangeInformation.Prefix);
  352.                             }
  353.                             XmlDiffView.HtmlWriteString(
  354.                                 writer, 
  355.                                 typeOfDifference, 
  356.                                 Tags.XmlOpenEnd);
  357.                         }
  358.                         else
  359.                         {
  360.                             this.DrawHtmlName(
  361.                                 writer, 
  362.                                 typeOfDifference, 
  363.                                 Tags.XmlCloseBegin,
  364.                                 Tags.XmlCloseEnd);
  365.                         }
  366.                     }
  367.                     else
  368.                     {
  369.                         XmlDiffView.HtmlWriteEmptyString(writer);
  370.                     }
  371.                     XmlDiffView.HtmlEndCell(writer);
  372.                 }
  373.                 XmlDiffView.HtmlEndRow(writer);
  374.             }
  375.         }
  376.         /// <summary>
  377.         /// Generates  output data in text form
  378.         /// </summary>
  379.         /// <param name="writer">output stream</param>
  380.         /// <param name="indent">number of indentations</param>
  381.         internal override void DrawText(
  382.             TextWriter writer,
  383.             int indent)
  384.         {
  385.             Debug.Assert(XmlNodeType.Element == NodeType);
  386.             switch (Operation)
  387.             {
  388.                 case XmlDiffViewOperation.Add:
  389.                     this.DrawTextNameAdd(
  390.                         writer,
  391.                         indent,
  392.                         Tags.XmlOpenBegin,
  393.                         string.Empty);
  394.                     break;
  395.                 case XmlDiffViewOperation.Change:
  396.                     this.DrawTextNameChange(
  397.                         writer,
  398.                         indent,
  399.                         Tags.XmlOpenBegin,
  400.                         string.Empty);
  401.                     break;
  402.                 case XmlDiffViewOperation.Ignore:
  403.                 case XmlDiffViewOperation.Match:
  404.                     // No change or ignored
  405.                     /* write out the element but leave the 
  406.                      * tag open in case there are attributes.
  407.                      */
  408.                     this.DrawTextName(
  409.                         writer,
  410.                         indent,
  411.                         Tags.XmlOpenBegin,
  412.                         string.Empty);
  413.                     break;
  414.                 case XmlDiffViewOperation.MoveFrom:
  415.                     this.DrawTextNameMoveFrom(
  416.                         writer,
  417.                         indent,
  418.                         Tags.XmlOpenBegin,
  419.                         string.Empty);
  420.                     break;
  421.                 case XmlDiffViewOperation.MoveTo:
  422.                     this.DrawTextNameMoveTo(
  423.                         writer,
  424.                         indent,
  425.                         Tags.XmlOpenBegin,
  426.                         string.Empty);
  427.                     break;
  428.                 case XmlDiffViewOperation.Remove:
  429.                     this.DrawTextNameDelete(
  430.                         writer,
  431.                         indent,
  432.                         Tags.XmlOpenBegin,
  433.                         string.Empty);
  434.                     break;
  435.                 default:
  436.                     Debug.Assert(false);
  437.                     break;
  438.             }
  439.             // attributes
  440.             this.DrawTextAttributes(writer, indent);
  441.             // if there is children
  442.             if (ChildNodes != null)
  443.             {
  444.                 // close start tag
  445.                 writer.Write(Tags.XmlOpenEnd +
  446.                     writer.NewLine);
  447.                 // process child nodes
  448.                 TextDrawChildNodes(writer, indent);
  449.                 // end element
  450.                 this.DrawTextName(
  451.                     writer,
  452.                     indent,
  453.                     Tags.XmlCloseBegin,
  454.                     Tags.XmlCloseEnd + writer.NewLine);
  455.             }
  456.             else
  457.             {
  458.                 // avoid the need for closing node name tag
  459.                 writer.Write(Tags.XmlOpenEndTerse +
  460.                     writer.NewLine);
  461.             }
  462.         }
  463.         /// <summary>
  464.         /// Generates attributes' output data in html form
  465.         /// </summary>
  466.         /// <param name="writer">output stream</param>
  467.         /// <param name="paneNo">Pane number, indicating
  468.         ///  the left (baseline) or right side (actual) of the 
  469.         ///  display</param>
  470.         private void DrawHtmlAttributes(
  471.             XmlWriter writer, 
  472.             int paneNo)
  473.         {
  474.             if (this.Attributes == null)
  475.             {
  476.                 return;
  477.             }
  478.             string attrIndent = string.Empty;
  479.             if (this.Attributes.NextSibbling != null)
  480.             {
  481.                 attrIndent = XmlDiffView.GetIndent(this.Name.Length + 2);
  482.             }
  483.             XmlDiffViewAttribute curAttr = this.Attributes;
  484.             while (curAttr != null)
  485.             {
  486.                 if (XmlDiffView.HtmlWriteToPane[(int)curAttr.Operation, paneNo])
  487.                 {
  488.                     if (curAttr == this.Attributes)
  489.                     {
  490.                         writer.WriteString(" ");
  491.                     }
  492.                     else
  493.                     {
  494.                         writer.WriteRaw(attrIndent);
  495.                     }
  496.                     if (curAttr.Operation == XmlDiffViewOperation.Change)
  497.                     {
  498.                         if (paneNo == 0)
  499.                         {
  500.                             this.DrawHtmlAttributeChange(
  501.                                 writer, 
  502.                                 curAttr, 
  503.                                 curAttr.LocalName, 
  504.                                 curAttr.Prefix, 
  505.                                 curAttr.AttributeValue);
  506.                         }
  507.                         else
  508.                         {
  509.                             this.DrawHtmlAttributeChange(
  510.                                 writer, 
  511.                                 curAttr, 
  512.                                 curAttr.ChangeInformation.LocalName, 
  513.                                 curAttr.ChangeInformation.Prefix,
  514.                                 curAttr.ChangeInformation.Subset);
  515.                         }
  516.                     }
  517.                     else
  518.                     {
  519.                         this.DrawHtmlAttribute(
  520.                             writer, 
  521.                             curAttr, 
  522.                             curAttr.Operation);
  523.                     }
  524.                 }
  525.                 else
  526.                 {
  527.                     XmlDiffView.HtmlWriteEmptyString(writer);
  528.                 }
  529.                 curAttr = (XmlDiffViewAttribute)curAttr.NextSibbling;
  530.                 if (curAttr != null)
  531.                 {
  532.                     XmlDiffView.HtmlBr(writer);
  533.                 }
  534.             }
  535.         }
  536.         /// <summary>
  537.         /// Generates atrributes' output data in text form
  538.         /// </summary>
  539.         /// <param name="writer">output stream</param>
  540.         /// <param name="indent">number of indentations</param>
  541.         private void DrawTextAttributes(
  542.             TextWriter writer,
  543.             int indent)
  544.         {
  545.             if (this.Attributes != null)
  546.             {
  547.                 indent += Indent.IncrementSize;
  548.                 XmlDiffViewAttribute curAttr = this.Attributes;
  549.                 while (curAttr != null)
  550.                 {
  551.                     if (curAttr == this.Attributes)
  552.                     {
  553.                         writer.Write(" ");
  554.                     }
  555.                     else
  556.                     {  // put subsequent attributes on their own line
  557.                         writer.Write(
  558.                             writer.NewLine + XmlDiffView.IndentText(indent));
  559.                     }
  560.                     // The attributes could have their own 
  561.                     // 'add'/'remove'/'move from'/ 'move to'/match/ignore 
  562.                     // attribute operations so we check for that now 
  563.                     switch (curAttr.Operation)
  564.                     {
  565.                         case XmlDiffViewOperation.Change:
  566.                             this.DrawTextAttributeChange(writer, curAttr);
  567.                             break;
  568.                         case XmlDiffViewOperation.Add:
  569.                         case XmlDiffViewOperation.Ignore:
  570.                         case XmlDiffViewOperation.MoveFrom:
  571.                         case XmlDiffViewOperation.MoveTo:
  572.                         case XmlDiffViewOperation.Remove:
  573.                         case XmlDiffViewOperation.Match:
  574.                             // for 'add'/'remove'/'move from'/'move to'/match
  575.                             // operations write out the baseline attributes 
  576.                             // data.
  577.                             this.DrawTextAttribute(writer, curAttr);
  578.                             break;
  579.                         default:
  580.                             // raise exception for new type of 
  581.                             // difference created in XmlDiff object.
  582.                             throw new ArgumentException(
  583.                                 "Unrecognised type of difference", 
  584.                                 "Operation");
  585.                     }
  586.                     curAttr = (XmlDiffViewAttribute)curAttr.NextSibbling;
  587.                 }
  588.             }
  589.         }
  590.         /// <summary>
  591.         /// Generates output data in html form for a difference due to
  592.         /// a change in element name.
  593.         /// </summary>
  594.         /// <param name="writer">output stream</param>
  595.         /// <param name="localName">name of the 
  596.         /// element (without the prefix)</param>
  597.         /// <param name="prefix">prefix</param>
  598.         private void DrawHtmlNameChange(
  599.             XmlWriter writer, 
  600.             string localName, 
  601.             string prefix)
  602.         {
  603.             if (prefix != string.Empty)
  604.             {
  605.                 XmlDiffView.HtmlWriteString(
  606.                     writer, 
  607.                     this.ignorePrefixes ? XmlDiffViewOperation.Ignore : (prefix == ChangeInformation.Prefix) ? XmlDiffViewOperation.Match : XmlDiffViewOperation.Change,
  608.                     prefix + ":");
  609.             }
  610.             XmlDiffView.HtmlWriteString(
  611.                 writer,
  612.                 (localName == ChangeInformation.LocalName) ? XmlDiffViewOperation.Match : XmlDiffViewOperation.Change,
  613.                 localName);
  614.         }
  615.         /// <summary>
  616.         /// Generates output data in text form for a difference due
  617.         /// to adding data.
  618.         /// </summary>
  619.         /// <param name="writer">output stream</param>
  620.         /// <param name="indent">number of indentations</param>
  621.         /// <param name="tagStart">xml tags at start of statement</param>
  622.         /// <param name="tagEnd">xml tags at end of statement</param>
  623.         private void DrawTextNameAdd(
  624.             TextWriter writer,
  625.             int indent,
  626.             string tagStart,
  627.             string tagEnd)
  628.         {
  629.             writer.Write(XmlDiffView.IndentText(indent) +
  630.                 tagStart);
  631.             if (this.Prefix != string.Empty)
  632.             {
  633.                 writer.Write(this.Prefix + ":");
  634.             }
  635.             writer.Write(Difference.Tag + 
  636.                 Difference.NodeAdded + this.LocalName);
  637.             writer.Write(tagEnd);
  638.         }
  639.         /// <summary>
  640.         /// Generates output data in text form for a difference due
  641.         /// to deleting data.
  642.         /// </summary>
  643.         /// <param name="writer">output stream</param>
  644.         /// <param name="indent">number of indentations</param>
  645.         /// <param name="tagStart">xml tags at start of statement</param>
  646.         /// <param name="tagEnd">xml tags at end of statement</param>
  647.         private void DrawTextNameDelete(
  648.             TextWriter writer,
  649.             int indent,
  650.             string tagStart,
  651.             string tagEnd)
  652.         {
  653.             writer.Write(XmlDiffView.IndentText(indent) +
  654.                 tagStart);
  655.             if (this.Prefix != string.Empty)
  656.             {
  657.                 writer.Write(this.Prefix + ":");
  658.             }
  659.             writer.Write(this.LocalName + " " + Difference.Tag +
  660.                 Difference.NodeDeleted);
  661.             writer.Write(tagEnd);
  662.         }
  663.         /// <summary>
  664.         /// Generates output data in text form for a difference due
  665.         /// to changing existing data.
  666.         /// </summary>
  667.         /// <param name="writer">output stream</param>
  668.         /// <param name="indent">number of indentations</param>
  669.         /// <param name="tagStart">xml tags at start of statement</param>
  670.         /// <param name="tagEnd">xml tags at end of statement</param>
  671.         private void DrawTextNameChange(
  672.             TextWriter writer,
  673.             int indent,
  674.             string tagStart,
  675.             string tagEnd)
  676.         {
  677.             writer.Write(XmlDiffView.IndentText(indent) +
  678.                 tagStart);
  679.             if (this.Prefix != string.Empty)
  680.             {
  681.                 writer.Write(this.Prefix + ":");
  682.             }
  683.             writer.Write(Difference.Tag + 
  684.                 Difference.ChangeBegin + 
  685.                 this.LocalName +
  686.                 Difference.ChangeTo + 
  687.                 ChangeInformation.LocalName + 
  688.                 Difference.ChangeEnd);
  689.             writer.Write(tagEnd);
  690.         }
  691.         /// <summary>
  692.         /// Generates output data in text form for a difference due
  693.         /// to moving data from a location.
  694.         /// </summary>
  695.         /// <param name="writer">output stream</param>
  696.         /// <param name="indent">number of indentations</param>
  697.         /// <param name="tagStart">xml tags at start of statement</param>
  698.         /// <param name="tagEnd">xml tags at end of statement</param>
  699.         private void DrawTextNameMoveFrom(
  700.             TextWriter writer,
  701.             int indent,
  702.             string tagStart,
  703.             string tagEnd)
  704.         {
  705.             writer.Write(XmlDiffView.IndentText(indent) +
  706.                 tagStart);
  707.             if (this.Prefix != string.Empty)
  708.             {
  709.                 writer.Write(this.Prefix + ":");
  710.             }
  711.             writer.Write(this.LocalName + " " +
  712.                 Difference.Tag +
  713.                 Difference.NodeMovedFromBegin + 
  714.                 OperationId + 
  715.                 Difference.NodeMovedFromEnd);
  716.             writer.Write(tagEnd);
  717.         }
  718.         /// <summary>
  719.         /// Generates output data in text form for a difference due
  720.         /// to moving data to a new location.
  721.         /// </summary>
  722.         /// <param name="writer">output stream</param>
  723.         /// <param name="indent">number of indentations</param>
  724.         /// <param name="tagStart">xml tags at start of statement</param>
  725.         /// <param name="tagEnd">xml tags at end of statement</param>
  726.         private void DrawTextNameMoveTo(
  727.             TextWriter writer,
  728.             int indent,
  729.             string tagStart,
  730.             string tagEnd)
  731.         {
  732.             writer.Write(XmlDiffView.IndentText(indent) +
  733.                 tagStart);
  734.             if (this.Prefix == string.Empty)
  735.             {
  736.                 writer.Write(this.Prefix + ":");
  737.             }
  738.             writer.Write(this.LocalName + " " +
  739.                 Difference.Tag +
  740.                 Difference.NodeMovedToBegin +
  741.                 OperationId +
  742.                 Difference.NodeMovedToEnd);
  743.             writer.Write(tagEnd);
  744.         }
  745.         /// <summary>
  746.         /// Generates output data in text form for a difference due
  747.         /// to adding data.
  748.         /// </summary>
  749.         /// <param name="writer">output stream</param>
  750.         /// <param name="typeOfDifference">type of difference</param>
  751.         /// <param name="tagStart">xml tags at start of statement</param>
  752.         /// <param name="tagEnd">xml tags at end of statement</param>
  753.         private void DrawHtmlName(
  754.             XmlWriter writer, 
  755.             XmlDiffViewOperation typeOfDifference, 
  756.             string tagStart, 
  757.             string tagEnd)
  758.         {
  759.             if (this.Prefix != string.Empty && this.ignorePrefixes)
  760.             {
  761.                 XmlDiffView.HtmlWriteString(
  762.                     writer, 
  763.                     typeOfDifference, 
  764.                     tagStart);
  765.                 XmlDiffView.HtmlWriteString(
  766.                     writer, 
  767.                     XmlDiffViewOperation.Ignore, 
  768.                     this.Prefix + ":");
  769.                 XmlDiffView.HtmlWriteString(
  770.                     writer, 
  771.                     typeOfDifference, 
  772.                     this.LocalName + tagEnd);
  773.             }
  774.             else
  775.             {
  776.                 XmlDiffView.HtmlWriteString(
  777.                     writer, 
  778.                     typeOfDifference, 
  779.                     tagStart + this.Name + tagEnd);
  780.             }
  781.         }
  782.         /// <summary>
  783.         /// Generates output data in text form for the name of the element.
  784.         /// </summary>
  785.         /// <param name="writer">output stream</param>
  786.         /// <param name="indent">number of indentations</param>
  787.         /// <param name="tagStart">xml tags at start of statement</param>
  788.         /// <param name="tagEnd">xml tags at end of statement</param>
  789.         private void DrawTextName(
  790.             TextWriter writer,
  791.             int indent,
  792.             string tagStart,
  793.             string tagEnd)
  794.         {
  795.             if (this.Prefix != string.Empty && this.ignorePrefixes)
  796.             {
  797.                 writer.Write(
  798.                     XmlDiffView.IndentText(indent) +
  799.                     tagStart +
  800.                     this.Prefix + ":" +
  801.                     this.LocalName + tagEnd);
  802.             }
  803.             else
  804.             {
  805.                 writer.Write(XmlDiffView.IndentText(indent) +
  806.                     tagStart + this.Name + tagEnd);
  807.             }
  808.         }
  809.         /// <summary>
  810.         /// Generates output data in html for a difference due
  811.         /// to changing attribute data.
  812.         /// </summary>
  813.         /// <param name="writer">output stream</param>
  814.         /// <param name="attr">Attribute object</param>
  815.         /// <param name="localName">name of attribute 
  816.         /// (without the prefix)</param>
  817.         /// <param name="prefix">xml attribute prefix</param>
  818.         /// <param name="attributeValue">The value for the attribute.</param>
  819.         private void DrawHtmlAttributeChange(
  820.             XmlWriter writer, 
  821.             XmlDiffViewAttribute attr, 
  822.             string localName, 
  823.             string prefix, 
  824.             string attributeValue)
  825.         {
  826.             if (prefix != string.Empty)
  827.             {
  828.                 XmlDiffView.HtmlWriteString(
  829.                     writer,
  830.                     this.ignorePrefixes ? XmlDiffViewOperation.Ignore : (attr.Prefix == attr.ChangeInformation.Prefix) ? XmlDiffViewOperation.Match : XmlDiffViewOperation.Change,
  831.                     prefix + ":");
  832.             }
  833.             XmlDiffView.HtmlWriteString(
  834.                 writer,
  835.                 (attr.LocalName == attr.ChangeInformation.LocalName) ? XmlDiffViewOperation.Match : XmlDiffViewOperation.Change,
  836.                 this.localName);
  837.             if (attr.AttributeValue != attr.ChangeInformation.Subset)
  838.             {
  839.                 XmlDiffView.HtmlWriteString(writer, "="");
  840.                 XmlDiffView.HtmlWriteString(
  841.                     writer, 
  842.                     XmlDiffViewOperation.Change, 
  843.                     attributeValue);
  844.                 XmlDiffView.HtmlWriteString(writer, """);
  845.             }
  846.             else
  847.             {
  848.                 XmlDiffView.HtmlWriteString(
  849.                     writer, 
  850.                     "="" + attributeValue + """);
  851.             }
  852.         }
  853.         /// <summary>
  854.         /// Generate text output data for a differences 
  855.         /// due to a change, which may or may not have been 
  856.         /// a change in the attribute.
  857.         /// </summary>
  858.         /// <param name="writer">output stream</param>
  859.         /// <param name="attr">Attribute object</param>
  860.         private void DrawTextAttributeChange(
  861.             TextWriter writer,
  862.             XmlDiffViewAttribute attr)
  863.         {
  864.             Debug.Assert(null != attr);
  865.             if (this.Prefix != string.Empty)
  866.             {
  867.                 //if the prefix changed then show the change
  868.                 XmlDiffViewOperation op = this.ignorePrefixes ? XmlDiffViewOperation.Ignore :
  869.                     (attr.Prefix == attr.ChangeInformation.Prefix) ? XmlDiffViewOperation.Match : XmlDiffViewOperation.Change;
  870.                 switch (op)
  871.                 {
  872.                     case XmlDiffViewOperation.Ignore:
  873.                     case XmlDiffViewOperation.Match:
  874.                         writer.Write(attr.Prefix + ":");
  875.                         break;
  876.                     case XmlDiffViewOperation.Change:
  877.                         // show the new prefix
  878.                         writer.Write(
  879.                             Difference.Tag + "=" + Difference.ChangeBegin +
  880.                             attr.Prefix + Difference.ChangeTo +
  881.                             attr.ChangeInformation.Prefix + 
  882.                             Difference.ChangeEnd);
  883.                         writer.Write(attr.ChangeInformation.Prefix + ":");
  884.                         break;
  885.                     default:
  886.                         Trace.WriteLine("Unexpected type of difference");
  887.                         throw new ArgumentException(
  888.                             "Unexpected type of difference", 
  889.                             "Operation");
  890.                 }
  891.             }
  892.             if (System.Diagnostics.Debugger.IsAttached)
  893.             {
  894.                 string debugMessage = "It is not appropriate to call this function" +
  895.                 "when the ChangeInformation object is null.";
  896.                 Debug.Assert(
  897.                     null != attr.ChangeInformation,
  898.                     debugMessage);
  899.             }
  900.             // something changed
  901.             if (attr.LocalName != attr.ChangeInformation.LocalName)
  902.             {
  903.                 // show the change in the name
  904.                 writer.Write(" " + attr.LocalName + "="" +
  905.                     Difference.Tag + "RenamedNode" +
  906.                     Difference.ChangeTo +
  907.                     attr.ChangeInformation.LocalName +
  908.                     Difference.ChangeEnd + "=");
  909.             }
  910.             else
  911.             {
  912.                 writer.Write(" " + attr.LocalName + "="");
  913.             }
  914.             // determine if the attribute value has changed
  915.             if (attr.AttributeValue != attr.ChangeInformation.Subset)
  916.             {
  917.                 // attribute value changed
  918.                 //Note: "xd_ChangeFrom('original value')To('new value')"
  919.                 string attributeValueChange =
  920.                     Difference.Tag + Difference.ChangeBegin +
  921.                     attr.AttributeValue +
  922.                     Difference.ChangeTo +
  923.                     RemoveTabsAndNewlines(attr.ChangeInformation.Subset) +
  924.                     Difference.ChangeEnd;
  925.                 writer.Write(attributeValueChange + """);
  926.             }
  927.             else
  928.             {
  929.                 // attribute value is same
  930.                 writer.Write(
  931.                     RemoveTabsAndNewlines(attr.AttributeValue) + """);
  932.             }
  933.         }
  934.         /// <summary>
  935.         /// Generate html output data for a differences 
  936.         /// due to a change in an attribute.
  937.         /// </summary>
  938.         /// <param name="writer">output stream</param>
  939.         /// <param name="attr">Attribute object</param>
  940.         /// <param name="typeOfDifference">type of difference</param>
  941.         private void DrawHtmlAttribute(
  942.             XmlWriter writer, 
  943.             XmlDiffViewAttribute attr, 
  944.             XmlDiffViewOperation typeOfDifference)
  945.         {
  946.             if (this.ignorePrefixes)
  947.             {
  948.                 if (attr.Prefix == "xmlns" || (attr.LocalName == "xmlns" && 
  949.                     attr.Prefix == string.Empty))
  950.                 {
  951.                     XmlDiffView.HtmlWriteString(
  952.                         writer, 
  953.                         XmlDiffViewOperation.Ignore, 
  954.                         attr.Name);
  955.                     XmlDiffView.HtmlWriteString(
  956.                         writer, 
  957.                         typeOfDifference, 
  958.                         "="" + attr.AttributeValue + """);
  959.                     return;
  960.                 }
  961.                 else if (attr.Prefix != string.Empty)
  962.                 {
  963.                     XmlDiffView.HtmlWriteString(
  964.                         writer, 
  965.                         XmlDiffViewOperation.Ignore, 
  966.                         attr.Prefix + ":");
  967.                     XmlDiffView.HtmlWriteString(
  968.                         writer, 
  969.                         typeOfDifference, 
  970.                         attr.LocalName + "="" + attr.AttributeValue + """);
  971.                     return;
  972.                 }
  973.             }
  974.             XmlDiffView.HtmlWriteString(
  975.                 writer, 
  976.                 typeOfDifference, 
  977.                 attr.Name + "="" + attr.AttributeValue + """);
  978.         }
  979.         
  980.         /// <summary>
  981.         /// Generate text output data for an unchanged attribute.
  982.         /// </summary>
  983.         /// <param name="writer">output stream</param>
  984.         /// <param name="attr">attribute object</param>
  985.         private void DrawTextAttribute(
  986.             TextWriter writer,
  987.             XmlDiffViewAttribute attr)
  988.         {
  989.             if (this.ignorePrefixes)
  990.             {
  991.                 if (attr.Prefix == "xmlns" || (attr.LocalName == "xmlns" && 
  992.                     attr.Prefix == string.Empty))
  993.                 {
  994.                     writer.Write(attr.Name);
  995.                     writer.Write("='" + 
  996.                         RemoveTabsAndNewlines(attr.AttributeValue) + "'");
  997.                     return;
  998.                 }
  999.                 else if (attr.Prefix != string.Empty)
  1000.                 {
  1001.                     writer.Write(attr.Prefix + ":");
  1002.                     writer.Write(attr.LocalName + "="" + 
  1003.                         RemoveTabsAndNewlines(attr.AttributeValue) + """);
  1004.                     return;
  1005.                 }
  1006.             }
  1007.             writer.Write(attr.Name + "="" + 
  1008.                 RemoveTabsAndNewlines(attr.AttributeValue) + """);
  1009.         }
  1010.         
  1011.         #endregion
  1012.         
  1013.    }
  1014. }