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

xml/soap/webservice

开发平台:

Visual C++

  1. //  ---------------------------------------------------------------------------
  2. // <copyright company="Microsoft Corporation" file="XmlDiffViewNode.cs">
  3. //     Copyright (c) Microsoft Corporation 2005
  4. // </copyright>
  5. // <project>
  6. //     XmlDiffView
  7. // </project>
  8. // <summary>
  9. //     Generate output data for the nodes
  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 data for the nodes
  23.     /// </summary>
  24.     internal abstract class XmlDiffViewNode 
  25.     {
  26.     
  27.         #region Member variables section
  28.         /// <summary>
  29.         /// a place to store change information 
  30.         /// (only if Operation == XmlDiffViewOperation.Change)
  31.         /// </summary>
  32.         protected ChangeInfo changeInfo = null;
  33.         /// <summary>
  34.         /// stores the node type value
  35.         /// </summary>
  36.         private XmlNodeType nodeTypeStore;
  37.         /// <summary>
  38.         /// Pointer to the next sibiling
  39.         /// </summary>
  40.         private XmlDiffViewNode nextSibilingStore = null;
  41.         /// <summary>
  42.         /// Pointer to the parent node
  43.         /// </summary>
  44.         private XmlDiffViewNode parentStore = null;
  45.         /// <summary>
  46.         /// The type of difference
  47.         /// </summary>
  48.         private XmlDiffViewOperation operation = XmlDiffViewOperation.Match;
  49.         
  50.         /// <summary>
  51.         /// Identification number for the difference
  52.         /// </summary>
  53.         private int operationId = 0; // operation id
  54.     
  55.         #endregion
  56.         
  57.         #region  Constructors section
  58.         /// <summary>
  59.         /// Constructor.
  60.         /// </summary>
  61.         /// <param name="nodeType">type of node</param>
  62.         internal XmlDiffViewNode(XmlNodeType nodeType) 
  63.         {
  64.             this.NodeType = nodeType;
  65.         }
  66.         #endregion
  67.         #region Properties section
  68.         /// <summary>
  69.         /// Abstract property to get the outer xml data
  70.         /// </summary>
  71.         public abstract string OuterXml
  72.         { 
  73.             get; 
  74.         }
  75.         
  76.         /// <summary>
  77.         /// Gets or sets an object contained changed data.
  78.         /// </summary>
  79.         public ChangeInfo ChangeInformation
  80.         {
  81.             get
  82.             {
  83.                 return this.changeInfo;
  84.             }
  85.             set
  86.             {
  87.                 this.changeInfo = value;
  88.             }
  89.         }
  90.         /// <summary>
  91.         /// Gets or sets the next sibling
  92.         /// </summary>
  93.         public XmlDiffViewNode NextSibbling
  94.         {
  95.             get
  96.             {
  97.                 return this.nextSibilingStore;
  98.             }
  99.             set
  100.             {
  101.                 this.nextSibilingStore = value;
  102.             }
  103.         }
  104.         /// <summary>
  105.         /// Gets or sets the parent node
  106.         /// </summary>
  107.         public XmlDiffViewNode Parent
  108.         {
  109.             get
  110.             {
  111.                 return this.parentStore;
  112.             }
  113.             set
  114.             {
  115.                 this.parentStore = value;
  116.             }
  117.         }
  118.         
  119.         /// <summary>
  120.         /// Gets or sets the type of node
  121.         /// </summary>
  122.         public XmlNodeType NodeType
  123.         {
  124.             get
  125.             {
  126.                 return this.nodeTypeStore;
  127.             }
  128.             set
  129.             {
  130.                 this.nodeTypeStore = value;
  131.             }
  132.         }
  133.         
  134.         /// <summary>
  135.         /// Gets or sets the type of difference.
  136.         /// </summary>
  137.         public XmlDiffViewOperation Operation
  138.         {
  139.             get
  140.             {
  141.                 return this.operation;
  142.             }
  143.             set
  144.             {
  145.                 this.operation = value;
  146.             }
  147.         }
  148.         
  149.         /// <summary>
  150.         /// Gets or sets the difference identifier number
  151.         /// </summary>
  152.         public int OperationId
  153.         {
  154.             get
  155.             {
  156.                 return this.operationId;
  157.             }
  158.             set
  159.             {
  160.                 this.operationId  = value;
  161.             }
  162.         }
  163.         
  164.         /// <summary>
  165.         /// Gets a null value
  166.         /// </summary>
  167.         internal virtual XmlDiffViewNode FirstChildNode 
  168.         {
  169.             get 
  170.             {
  171.                 return null; 
  172.             } 
  173.         }
  174.         #endregion
  175.         
  176.         #region Methods section
  177.         /// <summary>
  178.         /// Generate output text for a difference due to a change 
  179.         /// to the baseline data.
  180.         /// </summary>
  181.         /// <param name="writer">output data stream</param>
  182.         /// <param name="indent">size of the indent</param>
  183.         public void DrawTextNoChange(
  184.             TextWriter writer, 
  185.             int indent) 
  186.         {
  187.             Debug.Assert(this.NodeType != XmlNodeType.Element && this.NodeType != XmlNodeType.Attribute);
  188.             Debug.Assert(this.Operation != XmlDiffViewOperation.Change);
  189.             //bool closeElement = OutputNavigationHtml(writer);
  190.             string xmlText = this.OuterXml;
  191.             writer.Write(XmlDiffView.IndentText(indent) + 
  192.                 xmlText);
  193.         }
  194.     
  195.         /// <summary>
  196.         /// Abstract method to get a copy of a node
  197.         /// </summary>
  198.         /// <param name="deep">has children</param>
  199.         /// <returns>a node object</returns>
  200.         internal abstract XmlDiffViewNode Clone(bool deep);
  201.         
  202.         /// <summary>
  203.         /// Abstract method to generate html output data
  204.         /// </summary>
  205.         /// <param name="writer">data stream</param>
  206.         /// <param name="indent">size of indentation</param>
  207.         internal abstract void DrawHtml(XmlWriter writer, int indent);
  208.         /// <summary>
  209.         /// Abstract method to generate text output data
  210.         /// </summary>
  211.         /// <param name="writer">data stream</param>
  212.         /// <param name="indent">size of indentation</param>
  213.         internal abstract void DrawText(TextWriter writer, int indent);
  214.         /// <summary>
  215.         /// Generates output data in html form when the node has not changed
  216.         /// </summary>
  217.         /// <param name="writer">output data stream</param>
  218.         /// <param name="indent">size of indentation</param>
  219.         internal void DrawHtmlNoChange(XmlWriter writer, int indent) 
  220.         {
  221.             Debug.Assert(this.NodeType != XmlNodeType.Element && this.NodeType != XmlNodeType.Attribute);
  222.             Debug.Assert(this.Operation != XmlDiffViewOperation.Change);
  223.             XmlDiffView.HtmlStartRow(writer);
  224.             this.DrawLinkNode(writer);
  225.             for (int i = 0; i < 2; i++) 
  226.             {
  227.                 XmlDiffView.HtmlStartCell(writer, indent);
  228.                 if (XmlDiffView.HtmlWriteToPane[(int)this.Operation, i]) 
  229.                 {
  230.                     bool closeElement = this.OutputNavigationHtml(writer);
  231.                     XmlDiffView.HtmlWriteString(
  232.                         writer, 
  233.                         this.Operation, 
  234.                         this.OuterXml);
  235.                     if (closeElement) 
  236.                     {
  237.                         writer.WriteEndElement();
  238.                     }
  239.                 }
  240.                 else 
  241.                 {
  242.                     XmlDiffView.HtmlWriteEmptyString(writer);
  243.                 }
  244.                 XmlDiffView.HtmlEndCell(writer);
  245.             }
  246.             XmlDiffView.HtmlEndRow(writer);
  247.         }
  248.         internal void DrawLinkNode(XmlWriter writer) {
  249.             writer.WriteStartElement("td");
  250.             if (this.operationId != XmlDiffView.LastVisitedOpId) {
  251.                 XmlDiffView.LastVisitedOpId = this.operationId;
  252.                 bool prev = false;
  253.                 if (this.operationId != 0) {
  254.                     writer.WriteStartElement("a");
  255.                     writer.WriteAttributeString("name", "id" + operationId);
  256.                 }
  257.                 if (this.operationId > 1) {
  258.                     writer.WriteStartElement("a");
  259.                     writer.WriteAttributeString("href", "#id" + (operationId - 1));
  260.                     writer.WriteString("prev");
  261.                     writer.WriteEndElement();
  262.                     prev = true;
  263.                 }
  264.                 if (this.operationId > 0 && this.operationId+1 < XmlDiffView.LastOperationId) {
  265.                     if (prev) {
  266.                         writer.WriteStartElement("br");
  267.                         writer.WriteEndElement();
  268.                     }
  269.                     writer.WriteStartElement("a");
  270.                     writer.WriteAttributeString("href", "#id" + (operationId + 1));
  271.                     writer.WriteString("next");
  272.                     writer.WriteEndElement();
  273.                     writer.WriteStartElement("br");
  274.                     writer.WriteEndElement();
  275.                 }
  276.                 if (this.operationId != 0) {
  277.                     writer.WriteEndElement();
  278.                 }
  279.             }
  280.             writer.WriteEndElement();
  281.         }
  282.         /// <summary>
  283.         /// Adds bookmarks and links to navigate from and to the moved items
  284.         /// </summary>
  285.         /// <param name="writer">The output writer object</param>
  286.         /// <returns>A closing 'A' element is needed</returns>
  287.         /// <remarks>When this returns 'true' use the 'WriteEndElement' 
  288.         /// method later in the calling funtions to write the closing 'A' tag.</remarks>
  289.         protected bool OutputNavigationHtml(XmlWriter writer) 
  290.         {
  291.             if (this.Parent == null || this.Parent.Operation != this.Operation) 
  292.             {
  293.                 switch (this.Operation) 
  294.                 {
  295.                     case XmlDiffViewOperation.MoveFrom:
  296.                         writer.WriteStartElement("a");
  297.                         writer.WriteAttributeString("name", "move_from_" + this.OperationId);
  298.                         writer.WriteEndElement();
  299.                         writer.WriteStartElement("a");
  300.                         writer.WriteAttributeString("href", "#move_to_" + this.OperationId);
  301.                         return true;
  302.                     case XmlDiffViewOperation.MoveTo:
  303.                         writer.WriteStartElement("a");
  304.                         writer.WriteAttributeString("name", "move_to_" + this.OperationId);
  305.                         writer.WriteEndElement();
  306.                         writer.WriteStartElement("a");
  307.                         writer.WriteAttributeString("href", "#move_from_" + this.OperationId);
  308.                         return true;
  309.                 }
  310.             }
  311.             return false;
  312.         }
  313.         #endregion
  314.         
  315.         /// <summary>
  316.         /// Strips the provided text of tabs and newline characters  
  317.         /// </summary>
  318.         /// <param name="innerText">text from which to remove 
  319.         /// the special characters</param>
  320.         /// <returns>the statement after the special characters
  321.         /// have been removed</returns>
  322.         protected string RemoveTabsAndNewlines(string innerText)
  323.         {
  324.             const string tab = "t";
  325.             // Remove tabs
  326.             innerText = innerText.Replace(tab, String.Empty);
  327.             // remove newlines
  328.             innerText = innerText.Replace(Environment.NewLine, String.Empty);
  329.             // trim off leading and trailing spaces
  330.             innerText = innerText.Trim();
  331.             return innerText;
  332.         }
  333.         #region Subclasses section
  334.         /// <summary>
  335.         /// Class to hold values of the changed data.
  336.         /// </summary>
  337.         internal class ChangeInfo 
  338.         {
  339.             #region Member variables section
  340.             
  341.             /// <summary>
  342.             /// Name of the node without the prefix
  343.             /// </summary>
  344.             private string localName;
  345.             /// <summary>
  346.             /// Prefix for the node except for a DocumentType
  347.             /// node this holds the "attribute" value for the 'PUBLIC' "attribute".
  348.             /// </summary>
  349.             private string prefix;
  350.             /// <summary>
  351.             /// URI for the node except for a DocumentType
  352.             /// node this holds the "attribute" value for the 'SYSTEM' "attribute".
  353.             /// </summary>
  354.             private string namespaceUri;
  355.             /// <summary>
  356.             /// internal subset for a DocumentType node
  357.             /// </summary>
  358.             private string subset;
  359.             
  360.             #endregion
  361.             #region Properties section
  362.             /// <summary>
  363.             /// Gets or sets the xml node prefix (without the semi-colon) 
  364.             /// </summary>
  365.             /// <example>xls</example>
  366.             public string Prefix
  367.             {
  368.                 get
  369.                 {
  370.                     return this.prefix;
  371.                 }
  372.                 set
  373.                 {
  374.                     this.prefix = value;
  375.                 }
  376.             }
  377.             /// <summary>
  378.             /// Gets or sets the node name with, if present,
  379.             /// a prefix
  380.             /// </summary>
  381.             /// <example>xls:mynode</example>
  382.             public string Subset
  383.             {
  384.                 get
  385.                 {
  386.                     return this.subset;
  387.                 }
  388.                 set
  389.                 {
  390.                     this.subset = value;
  391.                 }
  392.             }
  393.             /// <summary>
  394.             /// Gets or sets the node name without a prefix.
  395.             /// </summary>
  396.             /// <example>mynode</example>
  397.             public string LocalName
  398.             {
  399.                 get
  400.                 {
  401.                     return this.localName;
  402.                 }
  403.                 set
  404.                 {
  405.                     this.localName = value;
  406.                 }
  407.             }
  408.             /// <summary>
  409.             /// Gets or sets the namespace Uniform 
  410.             /// Resource Identifier (URI).
  411.             /// </summary>
  412.             public string NamespaceUri
  413.             {
  414.                 get
  415.                 {
  416.                     return this.namespaceUri;
  417.                 }
  418.                 set
  419.                 {
  420.                     this.namespaceUri = value;
  421.                 }
  422.             }
  423.             
  424.             #endregion
  425.         }
  426.         #endregion
  427.     }
  428. }