diff --git a/src/Common/Updates.xsd b/src/Common/Updates.xsd
new file mode 100644
index 0000000..0d9ec39
--- /dev/null
+++ b/src/Common/Updates.xsd
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+ The name of the application being updated.
+
+
+
+
+ The location of the update xml page.
+
+
+
+
+ Location of the download page.
+
+
+
+
+ Location of the installation page.
+
+
+
+
+ Location of the page showing update history.
+
+
+
+
+ The frequency we need to check for updates to the application, any valid TimeSpan.
+
+
+
+
+
+
+
+ This element describes a new version of the application.
+
+
+
+
+
+ Description of a new feature added in this version.
+
+
+
+
+ Description of a bug fixed in this version.
+
+
+
+
+
+ The version number.
+
+
+
+
+
+
+
+
diff --git a/src/Common/Updates.xslt b/src/Common/Updates.xslt
new file mode 100644
index 0000000..6e85818
--- /dev/null
+++ b/src/Common/Updates.xslt
@@ -0,0 +1,76 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - Change History
+
+ |
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+ background:teal;color:white
+
+ |
+
+ Version
+ |
+
+
+
+
+ background:MediumTurquoise
+
+ Feature |
+
+
+ |
+
+
+
+ background:LightPink
+
+ Bug |
+
+
+ |
+
+
+
diff --git a/src/Common/changes.xml b/src/Common/changes.xml
index f62d471..8b4bdf3 100644
--- a/src/Common/changes.xml
+++ b/src/Common/changes.xml
@@ -1,6 +1,17 @@
+
+ Microsoft XML Diff
+ https://raw.githubusercontent.com/lovettchris/xmldiff/master/src/Common/changes.xml
+ https://www.nuget.org/packages/LovettSoftware.XmlDiff
+ https://www.nuget.org/packages/LovettSoftware.XmlDiff
+ https://github.com/microsoft/XmlNotepad/blob/master/src/Updates/Updates.xml
+ 1.00:00:00
+
+
+ Thanks to Mark Roberts for a cool new feature that omits identical output to make the diff HTML output scale better on huge XML files.
+
Add back strong naming for XmlDiffPatch.dll
diff --git a/src/Common/version.props b/src/Common/version.props
index 78092b7..cdef499 100644
--- a/src/Common/version.props
+++ b/src/Common/version.props
@@ -2,8 +2,8 @@
Lovett Software
Copyright © Lovett Software
- 1.0.8
- 1.0.8
- 1.0.8
+ 1.1.0
+ 1.1.0
+ 1.1.0
\ No newline at end of file
diff --git a/src/Common/version.txt b/src/Common/version.txt
index 337a6a8..1cc5f65 100644
--- a/src/Common/version.txt
+++ b/src/Common/version.txt
@@ -1 +1 @@
-1.0.8
\ No newline at end of file
+1.1.0
\ No newline at end of file
diff --git a/src/UnitTests/UnitTest1.cs b/src/UnitTests/UnitTest1.cs
index 507bf47..3261186 100644
--- a/src/UnitTests/UnitTest1.cs
+++ b/src/UnitTests/UnitTest1.cs
@@ -79,6 +79,27 @@ public void SideBySideDiffView()
}
}
+ [Fact]
+ public void SideBySideDiffViewCompact()
+ {
+ using (var col = new TempFileCollection())
+ {
+ var xmlSource = col.CreateTempFile("");
+ var xmlChanged = col.CreateTempFile("");
+
+ var view = new XmlDiffView();
+ var options = XmlDiffOptions.IgnoreChildOrder | XmlDiffOptions.IgnoreWhitespace;
+ var results = view.DifferencesSideBySideAsHtml(xmlSource, xmlChanged, false, options, true);
+
+ var diff = results.ReadToEnd();
+ Assert.Contains("root", diff);
+ Assert.Contains("banana", diff);
+ Assert.Contains("<temp", diff);
+ Assert.DoesNotContain("apple", diff);
+ Assert.DoesNotContain("elephant", diff);
+ }
+ }
+
private string ToComparibleString(XmlDocument doc)
{
// avoid comparing the hash.
diff --git a/src/XmlDiffView/XmlDiff.nuspec b/src/XmlDiffView/XmlDiff.nuspec
index 085ca38..1a0a980 100644
--- a/src/XmlDiffView/XmlDiff.nuspec
+++ b/src/XmlDiffView/XmlDiff.nuspec
@@ -2,7 +2,7 @@
LovettSoftware.XmlDiff
- 1.0.9
+ 1.1.0
Chris Lovett
A library that compares and merges XML files.
https://github.com/lovettchris/xmldiff
diff --git a/src/XmlDiffView/XmlDiffView.cs b/src/XmlDiffView/XmlDiffView.cs
index 66e26bd..e5b7eff 100644
--- a/src/XmlDiffView/XmlDiffView.cs
+++ b/src/XmlDiffView/XmlDiffView.cs
@@ -425,13 +425,15 @@ public XmlDiffViewResults DifferencesAsFormattedText(
/// the html output file
/// the file is only an Xml fragment
/// comparison filtering options
+ /// omit html output for identical xml elements
/// Differences were not found after filtering.
public bool DifferencesSideBySideAsHtml(
string sourceXmlFile,
string changedXmlFile,
string resultHtmlViewFile,
bool fragment,
- XmlDiffOptions options)
+ XmlDiffOptions options,
+ bool omitIdenticalHtmlOutput = false)
{
bool identicalData = this.DifferencesSideBySideAsHtml(
sourceXmlFile,
@@ -439,7 +441,8 @@ public bool DifferencesSideBySideAsHtml(
resultHtmlViewFile,
fragment,
true,
- options);
+ options,
+ omitIdenticalHtmlOutput);
return identicalData;
}
@@ -453,6 +456,7 @@ public bool DifferencesSideBySideAsHtml(
/// the file is only an Xml fragment
/// Append to existing output file
/// comparison filtering options
+ /// omit html output for identical xml elements
/// Differences were not found after filtering.
public bool DifferencesSideBySideAsHtml(
string sourceXmlFile,
@@ -460,7 +464,8 @@ public bool DifferencesSideBySideAsHtml(
string resultHtmlViewFile,
bool fragment,
bool appendToOutputFile,
- XmlDiffOptions options)
+ XmlDiffOptions options,
+ bool omitIdenticalHtmlOutput = false)
{
// Append to the specified output file.
FileMode mode;
@@ -481,11 +486,12 @@ public bool DifferencesSideBySideAsHtml(
bool identicalData;
try
{
- identicalData = this.DifferencesSideBySideAsHtml(
+ identicalData = this.InternalDifferencesSideBySideAsHtml(
sourceXmlFile,
changedXmlFile,
fragment,
options,
+ omitIdenticalHtmlOutput,
this.outputData);
}
finally
@@ -503,12 +509,14 @@ public bool DifferencesSideBySideAsHtml(
/// the actual (or target) file
/// the file is only an Xml fragment
/// comparison filtering options
+ /// omit html output for identical xml elements
/// Differences were not found after filtering.
public XmlDiffViewResults DifferencesSideBySideAsHtml(
string sourceXmlFile,
string changedXmlFile,
bool fragment,
- XmlDiffOptions options)
+ XmlDiffOptions options,
+ bool omitIdenticalHtmlOutput = false)
{
MemoryStream data = new MemoryStream();
@@ -521,11 +529,12 @@ public XmlDiffViewResults DifferencesSideBySideAsHtml(
bool identicalData = false;
try
{
- identicalData = this.DifferencesSideBySideAsHtml(
+ identicalData = this.InternalDifferencesSideBySideAsHtml(
sourceXmlFile,
changedXmlFile,
fragment,
options,
+ omitIdenticalHtmlOutput,
this.outputData);
}
@@ -556,12 +565,18 @@ public XmlDiffViewResults DifferencesSideBySideAsHtml(
/// TextWriter object (which may be a file).
///
/// Data stream for output
- public void GetHtml(TextWriter htmlOutput, bool omitMatches = false)
+ /// Omit matching lines to compress the size of the HTML output
+ /// HTML indent to show in points - default is padding-left: 10pt;
+ public void GetHtml(TextWriter htmlOutput, bool omitMatches = false, int indentPoints = 10)
{
LastVisitedOpId = 0;
XmlDiffViewNode.ResetLineNumbers();
XmlTextWriter writer = new XmlTextWriter(htmlOutput);
- this.viewDocument.DrawHtml(writer, 10, new XmlDiffViewRenderState { OmitMatches = omitMatches });
+ if (omitMatches)
+ {
+ this.viewDocument.PruneMatchingElements();
+ }
+ this.viewDocument.DrawHtml(writer, indentPoints);
}
#endregion
@@ -907,13 +922,15 @@ private bool GetDifferencesAsFormattedText(
/// actual file
/// xml data fragment
/// Comparison options
+ /// omit html output for identical xml elements
/// output data
/// data is identical
- private bool DifferencesSideBySideAsHtml(
+ private bool InternalDifferencesSideBySideAsHtml(
string sourceXmlFile,
string changedXmlFile,
bool fragment,
XmlDiffOptions options,
+ bool omitIdenticalHtmlOutput,
TextWriter resultHtml)
{
bool identicalData = this.MarkupBaselineWithChanges(
@@ -929,7 +946,7 @@ private bool DifferencesSideBySideAsHtml(
identicalData,
resultHtml);
- this.GetHtml(resultHtml);
+ this.GetHtml(resultHtml, omitIdenticalHtmlOutput);
this.SideBySideHtmlFooter(resultHtml);
diff --git a/src/XmlDiffView/XmlDiffViewAttribute.cs b/src/XmlDiffView/XmlDiffViewAttribute.cs
index 21d0a52..9a52b32 100644
--- a/src/XmlDiffView/XmlDiffViewAttribute.cs
+++ b/src/XmlDiffView/XmlDiffViewAttribute.cs
@@ -249,7 +249,7 @@ internal override XmlDiffViewNode Clone(bool deep)
/// output stream
/// size of indent
[Obsolete("This method should never be called", true)]
- internal override void DrawHtml(XmlWriter writer, int indent, XmlDiffViewRenderState renderState)
+ internal override void DrawHtml(XmlWriter writer, int indent)
{
throw new Exception("This method should never be called.");
}
diff --git a/src/XmlDiffView/XmlDiffViewCharData.cs b/src/XmlDiffView/XmlDiffViewCharData.cs
index f5b3531..fa889de 100644
--- a/src/XmlDiffView/XmlDiffViewCharData.cs
+++ b/src/XmlDiffView/XmlDiffViewCharData.cs
@@ -122,7 +122,7 @@ internal override XmlDiffViewNode Clone(bool deep)
///
/// output stream
/// number of indentations
- internal override void DrawHtml(XmlWriter writer, int indent, XmlDiffViewRenderState renderState)
+ internal override void DrawHtml(XmlWriter writer, int indent)
{
if (Operation == XmlDiffViewOperation.Change)
{
diff --git a/src/XmlDiffView/XmlDiffViewDocument.cs b/src/XmlDiffView/XmlDiffViewDocument.cs
index 81a6724..bf1b9ba 100644
--- a/src/XmlDiffView/XmlDiffViewDocument.cs
+++ b/src/XmlDiffView/XmlDiffViewDocument.cs
@@ -78,9 +78,9 @@ internal override XmlDiffViewNode Clone(bool deep)
/// output stream
/// number of indentations
///
- internal override void DrawHtml(XmlWriter writer, int indent, XmlDiffViewRenderState renderState)
+ internal override void DrawHtml(XmlWriter writer, int indent)
{
- HtmlDrawChildNodes(writer, indent, renderState);
+ HtmlDrawChildNodes(writer, indent);
}
///
diff --git a/src/XmlDiffView/XmlDiffViewDocumentType.cs b/src/XmlDiffView/XmlDiffViewDocumentType.cs
index 638ae30..fa84f3e 100644
--- a/src/XmlDiffView/XmlDiffViewDocumentType.cs
+++ b/src/XmlDiffView/XmlDiffViewDocumentType.cs
@@ -183,7 +183,7 @@ internal override XmlDiffViewNode Clone(bool deep)
///
/// output stream
/// number of indentations
- internal override void DrawHtml(XmlWriter writer, int indent, XmlDiffViewRenderState renderState)
+ internal override void DrawHtml(XmlWriter writer, int indent)
{
if (Operation == XmlDiffViewOperation.Change)
{
diff --git a/src/XmlDiffView/XmlDiffViewER.cs b/src/XmlDiffView/XmlDiffViewER.cs
index c34d7a2..296d2d1 100644
--- a/src/XmlDiffView/XmlDiffViewER.cs
+++ b/src/XmlDiffView/XmlDiffViewER.cs
@@ -78,7 +78,7 @@ internal override XmlDiffViewNode Clone(bool deep)
///
/// output data stream
/// size of indentation
- internal override void DrawHtml(XmlWriter writer, int indent, XmlDiffViewRenderState renderState)
+ internal override void DrawHtml(XmlWriter writer, int indent)
{
if (Operation == XmlDiffViewOperation.Change)
{
diff --git a/src/XmlDiffView/XmlDiffViewElement.cs b/src/XmlDiffView/XmlDiffViewElement.cs
index 56a2fb9..e32d248 100644
--- a/src/XmlDiffView/XmlDiffViewElement.cs
+++ b/src/XmlDiffView/XmlDiffViewElement.cs
@@ -165,10 +165,12 @@ public string Name
}
}
+ public bool HideAttributes { get; internal set; }
+
#endregion
-
+
#region Methods section
-
+
///
/// Gets an attribute object for the specified attribute name.
///
@@ -276,23 +278,8 @@ internal override XmlDiffViewNode Clone(bool deep)
///
/// output stream
/// number of indentations
- internal override void DrawHtml(XmlWriter writer, int indent, XmlDiffViewRenderState renderState)
+ internal override void DrawHtml(XmlWriter writer, int indent)
{
- if (renderState.OmitMatches)
- {
- if (IsDescendentAndSelfMatch(this))
- {
- if (!renderState.InOmissionBlock)
- {
- XmlDiffView.HtmlOmissionBlock(writer);
- renderState.InOmissionBlock = true;
- }
- return;
- }
-
- renderState.InOmissionBlock = false;
- }
-
XmlDiffViewOperation typeOfDifference = Operation;
bool closeElement = false;
XmlDiffView.HtmlStartRow(writer);
@@ -373,7 +360,7 @@ internal override void DrawHtml(XmlWriter writer, int indent, XmlDiffViewRenderS
// child nodes
if (ChildNodes != null)
{
- HtmlDrawChildNodes(writer, indent + XmlDiffView.DeltaIndent, renderState);
+ HtmlDrawChildNodes(writer, indent + XmlDiffView.DeltaIndent);
// end element
XmlDiffView.HtmlStartRow(writer);
@@ -431,37 +418,6 @@ internal override void DrawHtml(XmlWriter writer, int indent, XmlDiffViewRenderS
}
}
- ///
- /// Return true if node and all descendents are unchanged
- ///
- private static bool IsDescendentAndSelfMatch(XmlDiffViewNode node, bool rootNode = true)
- {
- while (true)
- {
- if (node.Operation != XmlDiffViewOperation.Match)
- {
- return false;
- }
-
- if (node is XmlDiffViewElement element && element.Attributes != null && !IsDescendentAndSelfMatch(element.Attributes, false))
- {
- return false;
- }
-
- if (node.FirstChildNode != null && !IsDescendentAndSelfMatch(node.FirstChildNode, false))
- {
- return false;
- }
-
- if (node.NextSibling == null || rootNode)
- {
- return true;
- }
-
- node = node.NextSibling;
- }
- }
-
///
/// Generates output data in text form
///
@@ -567,6 +523,12 @@ private void DrawHtmlAttributes(
{
return;
}
+ if (this.HideAttributes)
+ {
+ writer.WriteString(" ");
+ writer.WriteCharEntity('\u2026');
+ return;
+ }
string attrIndent = string.Empty;
if (this.Attributes.NextSibling != null)
{
diff --git a/src/XmlDiffView/XmlDiffViewNode.cs b/src/XmlDiffView/XmlDiffViewNode.cs
index e869c33..aa118bb 100644
--- a/src/XmlDiffView/XmlDiffViewNode.cs
+++ b/src/XmlDiffView/XmlDiffViewNode.cs
@@ -189,6 +189,11 @@ public XmlDiffViewOperation Operation
this.operation = value;
}
}
+
+ ///
+ /// This change is to be hidden from the rendered output.
+ ///
+ public bool Hidden { get; set; }
///
/// Gets or sets the difference identifier number
@@ -251,8 +256,7 @@ public void DrawTextNoChange(
///
/// data stream
/// size of indentation
- /// options and and additional state management for rendering
- internal abstract void DrawHtml(XmlWriter writer, int indent, XmlDiffViewRenderState renderState);
+ internal abstract void DrawHtml(XmlWriter writer, int indent);
///
/// Abstract method to generate text output data
diff --git a/src/XmlDiffView/XmlDiffViewPI.cs b/src/XmlDiffView/XmlDiffViewPI.cs
index 9616e6a..e2a96bb 100644
--- a/src/XmlDiffView/XmlDiffViewPI.cs
+++ b/src/XmlDiffView/XmlDiffViewPI.cs
@@ -101,7 +101,7 @@ internal override XmlDiffViewNode Clone(bool deep)
///
/// output data stream
/// size of indentation
- internal override void DrawHtml(XmlWriter writer, int indent, XmlDiffViewRenderState renderState)
+ internal override void DrawHtml(XmlWriter writer, int indent)
{
if (Operation == XmlDiffViewOperation.Change)
{
diff --git a/src/XmlDiffView/XmlDiffViewParentNode.cs b/src/XmlDiffView/XmlDiffViewParentNode.cs
index 06e0ac1..0658bd2 100644
--- a/src/XmlDiffView/XmlDiffViewParentNode.cs
+++ b/src/XmlDiffView/XmlDiffViewParentNode.cs
@@ -19,6 +19,7 @@ namespace Microsoft.XmlDiffPatch
using System.Xml;
using System.IO;
using System.Diagnostics;
+ using System.Runtime.CompilerServices;
///
/// Class to access the parent node object and its child node objects.
@@ -203,14 +204,99 @@ internal void InsertChildAfter(
///
/// output stream
/// number of indentations
- internal void HtmlDrawChildNodes(XmlWriter writer, int indent, XmlDiffViewRenderState xmlDiffViewRenderState)
+ internal void HtmlDrawChildNodes(XmlWriter writer, int indent)
{
XmlDiffViewNode curChild = this.ChildNodes;
+ bool hasHidden = false;
+ bool hasVisible = false;
while (curChild != null)
{
- curChild.DrawHtml(writer, indent, xmlDiffViewRenderState);
+ if (curChild.Hidden)
+ {
+ // consolidate adjacent hidden nodes into one elipsis.
+ hasHidden = true;
+ }
+ else
+ {
+ if (hasHidden)
+ {
+ WriteEllipsisRow(writer, indent);
+ hasHidden = false;
+ }
+ hasVisible = true;
+ curChild.DrawHtml(writer, indent);
+ }
curChild = curChild.NextSibling;
}
+ if (hasVisible && hasHidden)
+ {
+ WriteEllipsisRow(writer, indent);
+ }
+ }
+
+ internal void WriteEllipsisRow(XmlWriter writer, int indent)
+ {
+ XmlDiffView.HtmlStartRow(writer);
+ this.DrawLineNumber(writer);
+ XmlDiffView.HtmlStartCell(writer, indent);
+ writer.WriteCharEntity('\u2026');
+ XmlDiffView.HtmlEndCell(writer);
+ XmlDiffView.HtmlStartCell(writer, indent);
+ writer.WriteCharEntity('\u2026');
+ XmlDiffView.HtmlEndCell(writer);
+ XmlDiffView.HtmlEndRow(writer);
+ }
+
+ public bool PruneMatchingElements()
+ {
+ // XmlDiffView.HtmlOmissionBlock(writer);
+ bool pruned = true;
+ XmlDiffViewNode node = this.ChildNodes;
+ while (node != null)
+ {
+ var hidden = true;
+ if (node.Operation != XmlDiffViewOperation.Match)
+ {
+ hidden = false;
+ }
+ else if (node is XmlDiffViewElement element && element.Attributes != null)
+ {
+ bool foundChangedAttribute = false;
+ XmlDiffViewNode a = element.Attributes;
+ while (a != null)
+ {
+ if (a.Operation != XmlDiffViewOperation.Match)
+ {
+ hidden = false;
+ foundChangedAttribute = true;
+ break;
+ }
+ a = a.NextSibling;
+ }
+
+ if (!foundChangedAttribute)
+ {
+ element.HideAttributes = true;
+ }
+ }
+
+ if (node is XmlDiffViewParentNode container)
+ {
+ if (!container.PruneMatchingElements())
+ {
+ hidden = false; // have to show this element then
+ }
+ }
+
+ node.Hidden = hidden;
+ node = node.NextSibling;
+ if (!hidden)
+ {
+ // then pass this up the tree.
+ pruned = false;
+ }
+ }
+ return pruned;
}
///
diff --git a/src/XmlDiffView/XmlDiffViewRenderState.cs b/src/XmlDiffView/XmlDiffViewRenderState.cs
deleted file mode 100644
index 7759f38..0000000
--- a/src/XmlDiffView/XmlDiffViewRenderState.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Microsoft.XmlDiffPatch
-{
- internal class XmlDiffViewRenderState
- {
- public bool OmitMatches { get; set; }
- public bool InOmissionBlock { get; set; }
- }
-}
\ No newline at end of file
diff --git a/src/XmlDiffView/XmlDiffViewXmlDeclaration.cs b/src/XmlDiffView/XmlDiffViewXmlDeclaration.cs
index 072dd52..dc135e7 100644
--- a/src/XmlDiffView/XmlDiffViewXmlDeclaration.cs
+++ b/src/XmlDiffView/XmlDiffViewXmlDeclaration.cs
@@ -76,7 +76,7 @@ internal override XmlDiffViewNode Clone(bool deep)
///
/// output stream
/// number of indentations
- internal override void DrawHtml(XmlWriter writer, int indent, XmlDiffViewRenderState renderState)
+ internal override void DrawHtml(XmlWriter writer, int indent)
{
if (Operation == XmlDiffViewOperation.Change)
{