Skip to content

Commit 0f62731

Browse files
authored
Merge pull request #13 from swagfin/feature/xml-char-escaping
chore: added new config option XmlCharEscaping
2 parents ec3ef7a + 1a066de commit 0f62731

File tree

4 files changed

+72
-4
lines changed

4 files changed

+72
-4
lines changed

ObjectSemantics.NET.Tests/ObjectSemanticsTests.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -784,5 +784,53 @@ public void Should_Act_On_IfCondition_Having_Multiple_IF_Condition_Blocks_MultiL
784784
Assert.Equal(expectedResult, generatedTemplate, false, true, true);
785785
}
786786
#endregion
787+
788+
789+
#region Xml Char Escape Tests
790+
[Fact]
791+
public void Should_Escape_Xml_Char_If_Option_Is_Enabled()
792+
{
793+
//Create Model
794+
Student student = new Student { StudentName = "I've got \"special\" < & also >" };
795+
var template = new ObjectSemanticsTemplate
796+
{
797+
FileContents = @"{{ StudentName }}"
798+
};
799+
string generatedTemplate = TemplateMapper.Map(student, template, null, new TemplateMapperOptions
800+
{
801+
XmlCharEscaping = true
802+
});
803+
string expectedString = "I&apos;ve got &quot;special&quot; &lt; &amp; also &gt;";
804+
Assert.Equal(expectedString, generatedTemplate, false, true, true);
805+
}
806+
807+
808+
[Fact]
809+
public void Should_Escape_Xml_Char_In_LOOPS_If_Option_Is_Enabled()
810+
{
811+
//Create Model
812+
Student student = new Student
813+
{
814+
Invoices = new List<Invoice>
815+
{
816+
new Invoice{ Narration="I've got \"special\""},
817+
new Invoice{ Narration="I've got < & also >"}
818+
}
819+
};
820+
//Template
821+
var template = new ObjectSemanticsTemplate
822+
{
823+
FileContents = @"{{ #foreach(invoices) }} [{{ Narration }}] {{ #endforeach }}"
824+
};
825+
string generatedTemplate = TemplateMapper.Map(student, template, null, new TemplateMapperOptions
826+
{
827+
XmlCharEscaping = true
828+
});
829+
string expectedResult = @" [I&apos;ve got &quot;special&quot;] [I&apos;ve got &lt; &amp; also &gt;] ";
830+
Assert.Equal(expectedResult, generatedTemplate, false, true, true);
831+
}
832+
#endregion
833+
834+
787835
}
788836
}

ObjectSemantics.NET/Algorithim/GavinsAlgorithim.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public static class GavinsAlgorithim
6363
{
6464
ExtractedObjProperty objProperty = rowRecordValues.FirstOrDefault(x => x.Name.ToUpper().Equals(objLoopCode.TargetPropertyName.ToUpper()));
6565
if (objProperty != null)
66-
activeRow = activeRow.ReplaceFirstOccurrence(objLoopCode.ReplaceRef, objProperty.GetValueFromPropertyFormatted(objLoopCode.FormattingCommand));
66+
activeRow = activeRow.ReplaceFirstOccurrence(objLoopCode.ReplaceRef, objProperty.GetPropertyDisplayString(objLoopCode.FormattingCommand, options));
6767
else
6868
activeRow = activeRow.ReplaceFirstOccurrence(objLoopCode.ReplaceRef, objLoopCode.ReplaceCommand);
6969
}
@@ -85,7 +85,7 @@ public static class GavinsAlgorithim
8585
{
8686
ExtractedObjProperty property = objProperties.FirstOrDefault(x => x.Name.ToUpper().Equals(replaceCode.TargetPropertyName.ToUpper()));
8787
if (property != null)
88-
clonedTemplate.Template = clonedTemplate.Template.ReplaceFirstOccurrence(replaceCode.ReplaceRef, property.GetValueFromPropertyFormatted(replaceCode.FormattingCommand));
88+
clonedTemplate.Template = clonedTemplate.Template.ReplaceFirstOccurrence(replaceCode.ReplaceRef, property.GetPropertyDisplayString(replaceCode.FormattingCommand, options));
8989
else
9090
clonedTemplate.Template = clonedTemplate.Template.ReplaceFirstOccurrence(replaceCode.ReplaceRef, @"{{ ##command## }}".Replace("##command##", replaceCode.ReplaceCommand));
9191
}

ObjectSemantics.NET/Extensions/ExtractedObjPropertyExtensions.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4+
using System.Security;
5+
46
namespace ObjectSemantics.NET
57
{
68
public static class ExtractedObjPropertyExtensions
79
{
8-
public static string GetValueFromPropertyFormatted(this ExtractedObjProperty p, string customFormattingValue)
10+
public static string GetPropertyDisplayString(this ExtractedObjProperty p, string stringFormatting, TemplateMapperOptions templateMapperOptions)
11+
{
12+
string formattedPropertyString = GetAppliedPropertyFormatting(p, stringFormatting);
13+
//Apply Options to Property value string
14+
if (templateMapperOptions==null) return formattedPropertyString;
15+
if (templateMapperOptions.XmlCharEscaping)
16+
formattedPropertyString = SecurityElement.Escape(formattedPropertyString);
17+
return formattedPropertyString;
18+
}
19+
private static string GetAppliedPropertyFormatting(this ExtractedObjProperty p, string customFormattingValue)
920
{
1021
if (string.IsNullOrWhiteSpace(customFormattingValue))
1122
return p.StringFormatted;

ObjectSemantics.NET/TemplateMapperOptions.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@
22
{
33
public class TemplateMapperOptions
44
{
5-
5+
/// <summary>
6+
/// This will apply XML Character Escape on invalid characters in a Property Value String with their valid XML Equivalent
7+
/// Example of Characters;
8+
/// " &quot;
9+
/// ' &apos;
10+
/// < &lt;
11+
/// > &gt;
12+
/// & &amp;
13+
/// </summary>
14+
public bool XmlCharEscaping { get; set; } = false;
615
}
716
}

0 commit comments

Comments
 (0)