@joebigelow / wix-1 / commits / c122209d

Convert .wxl files namespaces

Fixes 6639

Rob Mensching committed Mar 19, 2022 at 11:47 UTC c122209d47ae055050dee3af2b83220914030b08
2 files changed +125 -2
src/wix/WixToolset.Converters/WixConverter.cs
+29 -2
@@ -60,6 +60,8 @@ namespace WixToolset.Converters
60 private static readonly XNamespace WixUiNamespace = "http://wixtoolset.org/schemas/v4/wxs/ui";
61 private static readonly XNamespace WixUtilNamespace = "http://wixtoolset.org/schemas/v4/wxs/util";
62 private static readonly XNamespace WixVSNamespace = "http://wixtoolset.org/schemas/v4/wxs/vs";
63 + private static readonly XNamespace WxlNamespace = "http://wixtoolset.org/schemas/v4/wxl";
64 + private static readonly XNamespace Wxl3Namespace = "http://schemas.microsoft.com/wix/2006/localization";
65
66 private static readonly XName AdminExecuteSequenceElementName = WixNamespace + "AdminExecuteSequence";
67 private static readonly XName AdminUISequenceSequenceElementName = WixNamespace + "AdminUISequence";
@@ -158,6 +160,10 @@ namespace WixToolset.Converters
160 private static readonly XName DependencyCheckAttributeName = WixDependencyNamespace + "Check";
161 private static readonly XName DependencyEnforceAttributeName = WixDependencyNamespace + "Enforce";
162
163 + private static readonly XName WixLocalization4ElementName = WxlNamespace + "WixLocalization";
164 + private static readonly XName WixLocalization3ElementName = Wxl3Namespace + "WixLocalization";
165 + private static readonly XName WixLocalizationElementWithoutNamespaceName = XNamespace.None + "WixLocalization";
166 +
167 private static readonly Dictionary<string, XNamespace> OldToNewNamespaceMapping = new Dictionary<string, XNamespace>()
168 {
169 { "http://schemas.microsoft.com/wix/BalExtension", "http://wixtoolset.org/schemas/v4/wxs/bal" },
@@ -263,6 +269,7 @@ namespace WixToolset.Converters
269 { WixConverter.IncludeElementWithoutNamespaceName, this.ConvertElementWithoutNamespace },
270 { WixConverter.VerbElementName, this.ConvertVerbElement },
271 { WixConverter.UIRefElementName, this.ConvertUIRefElement },
272 + { WixConverter.WixLocalizationElementWithoutNamespaceName, this.ConvertWixLocalizationElementWithoutNamespace },
273 };
274
275 this.Messaging = messaging;
@@ -551,11 +558,11 @@ namespace WixToolset.Converters
558 // Gather any deprecated namespaces, then update this element tree based on those deprecations.
559 var declaration = attribute;
560
554 - if (element.Name == Wix3ElementName || element.Name == Include3ElementName)
561 + if (element.Name == Wix3ElementName || element.Name == Include3ElementName || element.Name == WixLocalization3ElementName)
562 {
563 this.SourceVersion = 3;
564 }
558 - else if (element.Name == Wix4ElementName || element.Name == Include4ElementName)
565 + else if (element.Name == Wix4ElementName || element.Name == Include4ElementName || element.Name == WixLocalization4ElementName)
566 {
567 this.SourceVersion = 4;
568 }
@@ -1866,6 +1873,26 @@ namespace WixToolset.Converters
1873 }
1874 }
1875
1876 + /// <summary>
1877 + /// Converts a WixLocalization element.
1878 + /// </summary>
1879 + /// <param name="element">The WixLocalization element to convert.</param>
1880 + /// <returns>The converted element.</returns>
1881 + private void ConvertWixLocalizationElementWithoutNamespace(XElement element)
1882 + {
1883 + if (this.OnInformation(ConverterTestType.XmlnsMissing, element, "The xmlns attribute is missing. It must be present with a value of '{0}'.", WxlNamespace.NamespaceName))
1884 + {
1885 + element.Name = WxlNamespace.GetName(element.Name.LocalName);
1886 +
1887 + element.Add(new XAttribute("xmlns", WxlNamespace.NamespaceName)); // set the default namespace.
1888 +
1889 + foreach (var elementWithoutNamespace in element.DescendantsAndSelf().Where(e => XNamespace.None == e.Name.Namespace))
1890 + {
1891 + elementWithoutNamespace.Name = WxlNamespace.GetName(elementWithoutNamespace.Name.LocalName);
1892 + }
1893 + }
1894 + }
1895 +
1896 private void ConvertInnerTextToAttribute(XElement element, string attributeName)
1897 {
1898 if (TryGetInnerText(element, out var text) &&
src/wix/test/WixToolsetTest.Converters/LocalizationFixture.cs new
+96
@@ -0,0 +1,96 @@
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 WixToolsetTest.Converters
4 +{
5 + using System;
6 + using System.Xml.Linq;
7 + using WixBuildTools.TestSupport;
8 + using WixToolset.Converters;
9 + using WixToolsetTest.Converters.Mocks;
10 + using Xunit;
11 +
12 + public class LocalizationFixture : BaseConverterFixture
13 + {
14 + [Fact]
15 + public void EnsureNoXmlDeclaration()
16 + {
17 + var parse = String.Join(Environment.NewLine,
18 + "<?xml version='1.0' ?>",
19 + "<WixLocalization Culture='en-us'>",
20 + " <String Id='SomeId'>Value</String>",
21 + "</WixLocalization>");
22 +
23 + var expected = new[]
24 + {
25 + "<WixLocalization Culture=\"en-us\" xmlns=\"http://wixtoolset.org/schemas/v4/wxl\">",
26 + " <String Id=\"SomeId\">Value</String>",
27 + "</WixLocalization>"
28 + };
29 +
30 + var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
31 +
32 + var messaging = new MockMessaging();
33 + var converter = new WixConverter(messaging, 2, null, null);
34 +
35 + var errors = converter.ConvertDocument(document);
36 + Assert.Equal(2, errors);
37 +
38 + var actualLines = UnformattedDocumentLines(document);
39 + WixAssert.CompareLineByLine(expected, actualLines);
40 + }
41 +
42 + [Fact]
43 + public void EnsureNamespace()
44 + {
45 + var parse = String.Join(Environment.NewLine,
46 + "<WixLocalization Culture='en-us'>",
47 + " <String Id='SomeId'>Value</String>",
48 + "</WixLocalization>");
49 +
50 + var expected = new[]
51 + {
52 + "<WixLocalization Culture=\"en-us\" xmlns=\"http://wixtoolset.org/schemas/v4/wxl\">",
53 + " <String Id=\"SomeId\">Value</String>",
54 + "</WixLocalization>"
55 + };
56 +
57 + var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
58 +
59 + var messaging = new MockMessaging();
60 + var converter = new WixConverter(messaging, 2, null, null);
61 +
62 + var errors = converter.ConvertDocument(document);
63 + Assert.Equal(1, errors);
64 +
65 + var actualLines = UnformattedDocumentLines(document);
66 + WixAssert.CompareLineByLine(expected, actualLines);
67 + }
68 +
69 + [Fact]
70 + public void FixNamespace()
71 + {
72 + var parse = String.Join(Environment.NewLine,
73 + "<WixLocalization Culture='en-us' xmlns='http://schemas.microsoft.com/wix/2006/localization'>",
74 + " <String Id='SomeId'>Value</String>",
75 + "</WixLocalization>");
76 +
77 + var expected = new[]
78 + {
79 + "<WixLocalization Culture=\"en-us\" xmlns=\"http://wixtoolset.org/schemas/v4/wxl\">",
80 + " <String Id=\"SomeId\">Value</String>",
81 + "</WixLocalization>"
82 + };
83 +
84 + var document = XDocument.Parse(parse, LoadOptions.PreserveWhitespace | LoadOptions.SetLineInfo);
85 +
86 + var messaging = new MockMessaging();
87 + var converter = new WixConverter(messaging, 2, null, null);
88 +
89 + var errors = converter.ConvertDocument(document);
90 + Assert.Equal(1, errors);
91 +
92 + var actualLines = UnformattedDocumentLines(document);
93 + WixAssert.CompareLineByLine(expected, actualLines);
94 + }
95 + }
96 +}