diff options
Diffstat (limited to 'src/wix/WixInternal.Core.TestPackage/XmlNodeExtensions.cs')
-rw-r--r-- | src/wix/WixInternal.Core.TestPackage/XmlNodeExtensions.cs | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/wix/WixInternal.Core.TestPackage/XmlNodeExtensions.cs b/src/wix/WixInternal.Core.TestPackage/XmlNodeExtensions.cs new file mode 100644 index 00000000..4fb9b705 --- /dev/null +++ b/src/wix/WixInternal.Core.TestPackage/XmlNodeExtensions.cs | |||
@@ -0,0 +1,115 @@ | |||
1 | // Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. | ||
2 | |||
3 | namespace WixInternal.Core.TestPackage | ||
4 | { | ||
5 | using System.Collections.Generic; | ||
6 | using System.IO; | ||
7 | using System.Linq; | ||
8 | using System.Text.RegularExpressions; | ||
9 | using System.Xml; | ||
10 | |||
11 | /// <summary> | ||
12 | /// Utility class to help compare XML in tests using string comparisons by using single quotes and stripping all namespaces. | ||
13 | /// </summary> | ||
14 | public static class XmlNodeExtensions | ||
15 | { | ||
16 | /// <summary> | ||
17 | /// Adds root element around XML then returns it using single quotes and stripping all namespaces. | ||
18 | /// </summary> | ||
19 | /// <param name="xmlFragment"></param> | ||
20 | /// <param name="ignoredAttributesByElementName">Attributes for which the value should be set to '*'.</param> | ||
21 | /// <returns></returns> | ||
22 | public static string GetFragmentTestXml(this string xmlFragment, Dictionary<string, List<string>> ignoredAttributesByElementName = null) | ||
23 | { | ||
24 | return $"<root>{xmlFragment}</root>".GetTestXml(ignoredAttributesByElementName); | ||
25 | } | ||
26 | |||
27 | /// <summary> | ||
28 | /// Returns the node's outer XML using single quotes and stripping all namespaces. | ||
29 | /// </summary> | ||
30 | /// <param name="node"></param> | ||
31 | /// <param name="ignoredAttributesByElementName">Attributes for which the value should be set to '*'.</param> | ||
32 | /// <returns></returns> | ||
33 | public static string GetTestXml(this XmlNode node, Dictionary<string, List<string>> ignoredAttributesByElementName = null) | ||
34 | { | ||
35 | return node.OuterXml.GetTestXml(ignoredAttributesByElementName); | ||
36 | } | ||
37 | |||
38 | /// <summary> | ||
39 | /// Returns the XML using single quotes and stripping all namespaces. | ||
40 | /// </summary> | ||
41 | /// <param name="xml"></param> | ||
42 | /// <param name="ignoredAttributesByElementName">Attributes for which the value should be set to '*'.</param> | ||
43 | /// <returns></returns> | ||
44 | public static string GetTestXml(this string xml, Dictionary<string, List<string>> ignoredAttributesByElementName = null) | ||
45 | { | ||
46 | string formattedXml; | ||
47 | using (var sw = new StringWriter()) | ||
48 | using (var writer = new TestXmlWriter(sw)) | ||
49 | { | ||
50 | var doc = new XmlDocument(); | ||
51 | doc.LoadXml(xml); | ||
52 | |||
53 | if (ignoredAttributesByElementName != null) | ||
54 | { | ||
55 | HandleIgnoredAttributes(doc, ignoredAttributesByElementName); | ||
56 | } | ||
57 | |||
58 | doc.Save(writer); | ||
59 | formattedXml = sw.ToString(); | ||
60 | } | ||
61 | |||
62 | return Regex.Replace(formattedXml, " xmlns(:[^=]+)?='[^']*'", ""); | ||
63 | } | ||
64 | |||
65 | /// <summary> | ||
66 | /// Returns the XML for each node using single quotes and stripping all namespaces. | ||
67 | /// </summary> | ||
68 | /// <param name="nodeList"></param> | ||
69 | /// <param name="ignoredAttributesByElementName">Attributes for which the value should be set to '*'.</param> | ||
70 | /// <returns></returns> | ||
71 | public static string[] GetTestXmlLines(this XmlNodeList nodeList, Dictionary<string, List<string>> ignoredAttributesByElementName = null) | ||
72 | { | ||
73 | return nodeList.Cast<XmlNode>() | ||
74 | .Select(x => x.GetTestXml(ignoredAttributesByElementName)) | ||
75 | .ToArray(); | ||
76 | } | ||
77 | |||
78 | private static void HandleIgnoredAttributes(XmlNode node, Dictionary<string, List<string>> ignoredAttributesByElementName) | ||
79 | { | ||
80 | if (node.Attributes != null && ignoredAttributesByElementName.TryGetValue(node.LocalName, out var ignoredAttributes)) | ||
81 | { | ||
82 | foreach (var ignoredAttribute in ignoredAttributes) | ||
83 | { | ||
84 | var attribute = node.Attributes[ignoredAttribute]; | ||
85 | if (attribute != null) | ||
86 | { | ||
87 | attribute.Value = "*"; | ||
88 | } | ||
89 | } | ||
90 | } | ||
91 | |||
92 | if (node.ChildNodes != null) | ||
93 | { | ||
94 | foreach (XmlNode childNode in node.ChildNodes) | ||
95 | { | ||
96 | HandleIgnoredAttributes(childNode, ignoredAttributesByElementName); | ||
97 | } | ||
98 | } | ||
99 | } | ||
100 | |||
101 | private class TestXmlWriter : XmlTextWriter | ||
102 | { | ||
103 | public TestXmlWriter(TextWriter w) | ||
104 | : base(w) | ||
105 | { | ||
106 | this.QuoteChar = '\''; | ||
107 | } | ||
108 | |||
109 | public override void WriteStartDocument() | ||
110 | { | ||
111 | //OmitXmlDeclaration | ||
112 | } | ||
113 | } | ||
114 | } | ||
115 | } | ||