diff --git a/src/Cake.Common.Tests/Properties/Resources.Designer.cs b/src/Cake.Common.Tests/Properties/Resources.Designer.cs index e820ea1240..c82f75cde0 100644 --- a/src/Cake.Common.Tests/Properties/Resources.Designer.cs +++ b/src/Cake.Common.Tests/Properties/Resources.Designer.cs @@ -973,5 +973,44 @@ public static string XmlTransformation_Xsl { return ResourceManager.GetString("XmlTransformation_Xsl", resourceCulture); } } + + /// + /// Looks up a localized string similar to <?xml version="1.0" encoding="UTF-8"?> + ///<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> + ///<xsl:output method="html" encoding="utf-8"/> + ///<xsl:param name="BackgroundColor"></xsl:param> + ///<xsl:param name="Color"></xsl:param> + /// + ///<xsl:template match="/"> + ///<html> + /// <body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE"> + /// <xsl:for-each select="breakfast_menu/food"> + /// <div style="background-color:{$BackgroundColor};color:{$Color};padding:4px"> + /// [rest of string was truncated]";. + /// + public static string XmlTransformationWithArguments_Xsl { + get { + return ResourceManager.GetString("XmlTransformationWithArguments_Xsl", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <?xml version="1.0" encoding="UTF-8"?> + ///<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:input="http://example.com" exclude-result-prefixes="input" version="1.0"> + ///<xsl:output method="html" encoding="utf-8"/> + ///<xsl:param name="input:BackgroundColor"></xsl:param> + ///<xsl:param name="input:Color"></xsl:param> + /// + ///<xsl:template match="/"> + ///<html> + /// <body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE"> + /// <xsl:for-each select="breakfast_menu/food"> + /// <di [rest of string was truncated]";. + /// + public static string XmlTransformationWithArgumentsAndNamespace_Xsl { + get { + return ResourceManager.GetString("XmlTransformationWithArgumentsAndNamespace_Xsl", resourceCulture); + } + } } } diff --git a/src/Cake.Common.Tests/Properties/Resources.resx b/src/Cake.Common.Tests/Properties/Resources.resx index 2789d22b81..69d086648b 100644 --- a/src/Cake.Common.Tests/Properties/Resources.resx +++ b/src/Cake.Common.Tests/Properties/Resources.resx @@ -1433,4 +1433,72 @@ Global EndGlobalSection EndGlobal + + <?xml version="1.0" encoding="UTF-8"?> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> +<xsl:output method="html" encoding="utf-8"/> +<xsl:param name="BackgroundColor"></xsl:param> +<xsl:param name="Color"></xsl:param> + +<xsl:template match="/"> +<html> + <body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE"> + <xsl:for-each select="breakfast_menu/food"> + <div style="background-color:{$BackgroundColor};color:{$Color};padding:4px"> + <span style="font-weight:bold"> + <xsl:value-of select="name" /> + - + </span> + <xsl:value-of select="price" /> + </div> + <div style="margin-left:20px;margin-bottom:1em;font-size:10pt"> + <p> + <xsl:value-of select="description" /> + <span style="font-style:italic"> + ( + <xsl:value-of select="calories" /> + calories per serving) + </span> + </p> + </div> + </xsl:for-each> + </body> +</html> +</xsl:template> +</xsl:stylesheet> + + + <?xml version="1.0" encoding="UTF-8"?> +<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:input="http://example.com" exclude-result-prefixes="input" version="1.0"> +<xsl:output method="html" encoding="utf-8"/> +<xsl:param name="input:BackgroundColor"></xsl:param> +<xsl:param name="input:Color"></xsl:param> + +<xsl:template match="/"> +<html> + <body style="font-family:Arial;font-size:12pt;background-color:#EEEEEE"> + <xsl:for-each select="breakfast_menu/food"> + <div style="background-color:{$input:BackgroundColor};color:{$input:Color};padding:4px"> + <span style="font-weight:bold"> + <xsl:value-of select="name" /> + - + </span> + <xsl:value-of select="price" /> + </div> + <div style="margin-left:20px;margin-bottom:1em;font-size:10pt"> + <p> + <xsl:value-of select="description" /> + <span style="font-style:italic"> + ( + <xsl:value-of select="calories" /> + calories per serving) + </span> + </p> + </div> + </xsl:for-each> + </body> +</html> +</xsl:template> +</xsl:stylesheet> + \ No newline at end of file diff --git a/src/Cake.Common.Tests/Unit/XML/XmlTransformationTests.cs b/src/Cake.Common.Tests/Unit/XML/XmlTransformationTests.cs index 710991d93a..c626da2e44 100644 --- a/src/Cake.Common.Tests/Unit/XML/XmlTransformationTests.cs +++ b/src/Cake.Common.Tests/Unit/XML/XmlTransformationTests.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using System.Text; +using System.Xml.Xsl; using Cake.Common.Tests.Fixtures; using Cake.Common.Tests.Properties; using Cake.Common.Xml; @@ -240,6 +241,56 @@ public void Should_Throw_If_String_Settings_Was_Null() // Then AssertEx.IsArgumentNullException(result, "settings"); } + + [Fact] + public void Should_Throw_If_XslArguments_Was_Null() + { + // Given + var xml = Resources.XmlTransformation_Xml; + var xsl = Resources.XmlTransformation_Xsl; + + // When + var result = Record.Exception(() => XmlTransformation.Transform(xsl, null, xml)); + + // Then + AssertEx.IsArgumentNullException(result, "arguments"); + } + + [Fact] + public void Should_Transform_Xml_String_And_Xsl_String_WithArguments_To_Result_String() + { + // Given + var xml = Resources.XmlTransformation_Xml; + var xsl = Resources.XmlTransformationWithArguments_Xsl; + var htm = Resources.XmlTransformation_Htm_NoXmlDeclaration; + var arguments = new XsltArgumentList(); + arguments.AddParam("BackgroundColor", string.Empty, "teal"); + arguments.AddParam("Color", string.Empty, "white"); + + // When + var result = XmlTransformation.Transform(xsl, arguments, xml); + + // Then + Assert.Equal(htm, result, ignoreLineEndingDifferences: true); + } + + [Fact] + public void Should_Transform_Xml_String_And_Xsl_String_WithArgumentsAndNamespace_To_Result_String() + { + // Given + var xml = Resources.XmlTransformation_Xml; + var xsl = Resources.XmlTransformationWithArgumentsAndNamespace_Xsl; + var htm = Resources.XmlTransformation_Htm_NoXmlDeclaration; + var arguments = new XsltArgumentList(); + arguments.AddParam("BackgroundColor", "http://example.com", "teal"); + arguments.AddParam("Color", "http://example.com", "white"); + + // When + var result = XmlTransformation.Transform(xsl, arguments, xml); + + // Then + Assert.Equal(htm, result, ignoreLineEndingDifferences: true); + } } } } \ No newline at end of file diff --git a/src/Cake.Common/Polyfill/XmlTransformationHelper.cs b/src/Cake.Common/Polyfill/XmlTransformationHelper.cs index f86654f431..a5cdd787bf 100644 --- a/src/Cake.Common/Polyfill/XmlTransformationHelper.cs +++ b/src/Cake.Common/Polyfill/XmlTransformationHelper.cs @@ -9,11 +9,11 @@ namespace Cake.Common.Polyfill { internal static class XmlTransformationHelper { - public static void Transform(XmlReader xsl, XmlReader xml, XmlWriter result) + public static void Transform(XmlReader xsl, XsltArgumentList arguments, XmlReader xml, XmlWriter result) { var xslTransform = new XslCompiledTransform(); xslTransform.Load(xsl); - xslTransform.Transform(xml, result); + xslTransform.Transform(xml, arguments, result); } } } diff --git a/src/Cake.Common/Xml/XmlTransformation.cs b/src/Cake.Common/Xml/XmlTransformation.cs index eaeac17c4e..feee1446cf 100644 --- a/src/Cake.Common/Xml/XmlTransformation.cs +++ b/src/Cake.Common/Xml/XmlTransformation.cs @@ -6,6 +6,7 @@ using System.IO; using System.Text; using System.Xml; +using System.Xml.Xsl; using Cake.Common.Polyfill; using Cake.Core; using Cake.Core.IO; @@ -35,7 +36,8 @@ public static string Transform(string xsl, string xml) Encoding = new UTF8Encoding(false) }; - return Transform(xsl, xml, settings); + var arguments = new XsltArgumentList(); + return Transform(xsl, arguments, xml, settings); } /// @@ -46,12 +48,49 @@ public static string Transform(string xsl, string xml) /// Settings for result file xml transformation. /// Transformed XML string. public static string Transform(string xsl, string xml, XmlTransformationSettings settings) + { + var arguments = new XsltArgumentList(); + return Transform(xsl, arguments, xml, settings); + } + + /// + /// Performs XML XSL transformation + /// + /// XML style sheet. + /// XSLT argument list. + /// XML data. + /// Transformed XML string. + public static string Transform(string xsl, XsltArgumentList arguments, string xml) + { + var settings = new XmlTransformationSettings + { + OmitXmlDeclaration = true, + Encoding = new UTF8Encoding(false) + }; + + return Transform(xsl, arguments, xml, settings); + } + + /// + /// Performs XML XSL transformation + /// + /// XML style sheet. + /// XSLT argument list. + /// XML data. + /// Settings for result file xml transformation. + /// Transformed XML string. + public static string Transform(string xsl, XsltArgumentList arguments, string xml, XmlTransformationSettings settings) { if (string.IsNullOrWhiteSpace(xsl)) { throw new ArgumentNullException(nameof(xsl), "Null or empty XML style sheet supplied."); } + if (arguments == null) + { + throw new ArgumentNullException(nameof(arguments), "Null XSLT argument list supplied."); + } + if (string.IsNullOrWhiteSpace(xml)) { throw new ArgumentNullException(nameof(xml), "Null or empty XML data supplied."); @@ -68,7 +107,7 @@ public static string Transform(string xsl, string xml, XmlTransformationSettings { using (var result = new MemoryStream()) { - Transform(xslReader, xmlReader, result, settings.XmlWriterSettings); + Transform(xslReader, arguments, xmlReader, result, settings.XmlWriterSettings); result.Position = 0; return settings.Encoding.GetString(result.ToArray()); } @@ -85,7 +124,8 @@ public static string Transform(string xsl, string xml, XmlTransformationSettings public static void Transform(IFileSystem fileSystem, FilePath xslPath, FilePath xmlPath, FilePath resultPath) { var settings = new XmlTransformationSettings(); - Transform(fileSystem, xslPath, xmlPath, resultPath, settings); + var arguments = new XsltArgumentList(); + Transform(fileSystem, xslPath, arguments, xmlPath, resultPath, settings); } /// @@ -97,6 +137,35 @@ public static void Transform(IFileSystem fileSystem, FilePath xslPath, FilePath /// Transformation result path. /// Settings for result file xml transformation. public static void Transform(IFileSystem fileSystem, FilePath xslPath, FilePath xmlPath, FilePath resultPath, XmlTransformationSettings settings) + { + var arguments = new XsltArgumentList(); + Transform(fileSystem, xslPath, arguments, xmlPath, resultPath, settings); + } + + /// + /// Performs XML XSL transformation + /// + /// The file system. + /// Path to xml style sheet. + /// XSLT argument list. + /// Path xml data. + /// Transformation result path. + public static void Transform(IFileSystem fileSystem, FilePath xslPath, XsltArgumentList arguments, FilePath xmlPath, FilePath resultPath) + { + var settings = new XmlTransformationSettings(); + Transform(fileSystem, xslPath, arguments, xmlPath, resultPath, settings); + } + + /// + /// Performs XML XSL transformation + /// + /// The file system. + /// Path to xml style sheet. + /// XSLT argument list. + /// Path xml data. + /// Transformation result path. + /// Settings for result file xml transformation. + public static void Transform(IFileSystem fileSystem, FilePath xslPath, XsltArgumentList arguments, FilePath xmlPath, FilePath resultPath, XmlTransformationSettings settings) { if (fileSystem == null) { @@ -108,6 +177,11 @@ public static void Transform(IFileSystem fileSystem, FilePath xslPath, FilePath throw new ArgumentNullException(nameof(xslPath), "Null XML style sheet path supplied."); } + if (arguments == null) + { + throw new ArgumentNullException(nameof(arguments), "Null XSLT argument list supplied."); + } + if (xmlPath == null) { throw new ArgumentNullException(nameof(xmlPath), "Null XML data path supplied."); @@ -153,8 +227,7 @@ public static void Transform(IFileSystem fileSystem, FilePath xslPath, FilePath xmlReader = XmlReader.Create(xmlStream); var resultWriter = XmlWriter.Create(resultStream, settings.XmlWriterSettings); - - Transform(xslReader, xmlReader, resultWriter); + Transform(xslReader, arguments, xmlReader, resultWriter); } } @@ -162,16 +235,22 @@ public static void Transform(IFileSystem fileSystem, FilePath xslPath, FilePath /// Performs XML XSL transformation. /// /// XML style sheet. + /// XSLT argument list. /// XML data. /// Transformation result. /// Optional settings for result file xml writer. - private static void Transform(TextReader xsl, TextReader xml, Stream result, XmlWriterSettings settings = null) + private static void Transform(TextReader xsl, XsltArgumentList arguments, TextReader xml, Stream result, XmlWriterSettings settings = null) { if (xsl == null) { throw new ArgumentNullException(nameof(xsl), "Null XML style sheet supplied."); } + if (arguments == null) + { + throw new ArgumentNullException(nameof(arguments), "Null XSLT argument list supplied."); + } + if (xml == null) { throw new ArgumentNullException(nameof(xml), "Null XML data supplied."); @@ -190,22 +269,28 @@ private static void Transform(TextReader xsl, TextReader xml, Stream result, Xml var xslXmlReader = XmlReader.Create(xsl); var xmlXmlReader = XmlReader.Create(xml); var resultXmlTextWriter = XmlWriter.Create(result, settings); - Transform(xslXmlReader, xmlXmlReader, resultXmlTextWriter); + Transform(xslXmlReader, arguments, xmlXmlReader, resultXmlTextWriter); } /// /// Performs XML XSL transformation. /// /// XML style sheet. + /// XSLT argument list. /// XML data. /// Transformation result. - private static void Transform(XmlReader xsl, XmlReader xml, XmlWriter result) + private static void Transform(XmlReader xsl, XsltArgumentList arguments, XmlReader xml, XmlWriter result) { if (xsl == null) { throw new ArgumentNullException(nameof(xsl), "Null XML style sheet supplied."); } + if (arguments == null) + { + throw new ArgumentNullException(nameof(arguments), "Null XSLT argument list supplied."); + } + if (xml == null) { throw new ArgumentNullException(nameof(xml), "Null XML data supplied."); @@ -216,7 +301,7 @@ private static void Transform(XmlReader xsl, XmlReader xml, XmlWriter result) throw new ArgumentNullException(nameof(result), "Null result supplied."); } - XmlTransformationHelper.Transform(xsl, xml, result); + XmlTransformationHelper.Transform(xsl, arguments, xml, result); } } } \ No newline at end of file