Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip... #44

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
<MsBuildAllProjects>$(MsBuildAllProjects);$(MsBuildThisFileFullPath)</MsBuildAllProjects>
</PropertyGroup>

<!--<PropertyGroup>
<VersionPrefix>1.0.11.0</VersionPrefix>
</PropertyGroup>-->
<PropertyGroup>
<VersionPrefix>1.2.0.0</VersionPrefix>
</PropertyGroup>

<Choose>
<!-- The environment variable `Prerelease` is set in the azure-pipelines.yml file. -->
Expand Down
21 changes: 21 additions & 0 deletions XPath2.Net.sln
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XQTSRunConsole", "src\XQTSR
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XPath2.Tests", "tests\XPath2.Tests\XPath2.Tests.csproj", "{31DC2EF8-C3FE-467D-84BE-FB5D956E6100}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XPath2.Extensions.Core", "src\XPath2.Extensions.Core\XPath2.Extensions.Core.csproj", "{1C326CF6-DEC2-4538-B46E-B045D3F7AFC3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XPath2.Extensions.NewtonsoftJson", "src\XPath2.Extensions.NewtonsoftJson\XPath2.Extensions.NewtonsoftJson.csproj", "{D267CE1F-60E1-47F4-82EE-6FF3CBED9BA2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "XPath2.Extensions.SystemTextJson", "src\XPath2.Extensions.SystemTextJson\XPath2.Extensions.SystemTextJson.csproj", "{28876979-CB85-44E4-96F1-537845257964}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -67,6 +73,18 @@ Global
{31DC2EF8-C3FE-467D-84BE-FB5D956E6100}.Debug|Any CPU.Build.0 = Debug|Any CPU
{31DC2EF8-C3FE-467D-84BE-FB5D956E6100}.Release|Any CPU.ActiveCfg = Release|Any CPU
{31DC2EF8-C3FE-467D-84BE-FB5D956E6100}.Release|Any CPU.Build.0 = Release|Any CPU
{1C326CF6-DEC2-4538-B46E-B045D3F7AFC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1C326CF6-DEC2-4538-B46E-B045D3F7AFC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1C326CF6-DEC2-4538-B46E-B045D3F7AFC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1C326CF6-DEC2-4538-B46E-B045D3F7AFC3}.Release|Any CPU.Build.0 = Release|Any CPU
{D267CE1F-60E1-47F4-82EE-6FF3CBED9BA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D267CE1F-60E1-47F4-82EE-6FF3CBED9BA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D267CE1F-60E1-47F4-82EE-6FF3CBED9BA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D267CE1F-60E1-47F4-82EE-6FF3CBED9BA2}.Release|Any CPU.Build.0 = Release|Any CPU
{28876979-CB85-44E4-96F1-537845257964}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{28876979-CB85-44E4-96F1-537845257964}.Debug|Any CPU.Build.0 = Debug|Any CPU
{28876979-CB85-44E4-96F1-537845257964}.Release|Any CPU.ActiveCfg = Release|Any CPU
{28876979-CB85-44E4-96F1-537845257964}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -78,6 +96,9 @@ Global
{D3804228-91F4-4502-9595-39584EBB0000} = {0C331956-D83C-4A5C-8A73-6B948ADEA559}
{D439F305-067F-4ABE-808A-D6832BF3F291} = {E2D9AE26-4F0F-4D09-BFD2-434DE9BDF433}
{31DC2EF8-C3FE-467D-84BE-FB5D956E6100} = {E2D9AE26-4F0F-4D09-BFD2-434DE9BDF433}
{1C326CF6-DEC2-4538-B46E-B045D3F7AFC3} = {0C331956-D83C-4A5C-8A73-6B948ADEA559}
{D267CE1F-60E1-47F4-82EE-6FF3CBED9BA2} = {0C331956-D83C-4A5C-8A73-6B948ADEA559}
{28876979-CB85-44E4-96F1-537845257964} = {0C331956-D83C-4A5C-8A73-6B948ADEA559}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {66C0CAE3-D093-4276-BCAC-BC3749408CE9}
Expand Down
138 changes: 138 additions & 0 deletions src/XPath2.Extensions.Core/FunctionTableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
using System;
using System.Text;
using Wmhelp.XPath2.MS;

namespace Wmhelp.XPath2.Extensions.Core
{
public static class FunctionTableExtensions
{
/// <summary>
/// Extend the XPath2 FunctionTable with:
/// - generate-id
/// - base64encode
/// - base64decode
/// </summary>
/// <param name="functionTable">The function table.</param>
public static void AddCoreExtensions(this FunctionTable functionTable)
{
functionTable.AddGenerateId();
functionTable.AddBase64Encode();
functionTable.AddBase64Decode();
}

/// <summary>
/// Extend the XPath2 FunctionTable with 'generate-id' function to generate a Guid (http://www.w3schools.com/xsl/func_generateid.asp)
/// </summary>
/// <param name="functionTable">The function table.</param>
public static void AddGenerateId(this FunctionTable functionTable)
{
functionTable.Add(XmlReservedNs.NsXQueryFunc, "generate-id", 0, XPath2ResultType.String, (context, provider, args) => Guid.NewGuid().ToString().ToLower());
}

/// <summary>
/// Extend the XPath2 FunctionTable with 'base64encode' function to encode a string to base64 string.
/// </summary>
/// <param name="functionTable">The function table.</param>
public static void AddBase64Encode(this FunctionTable functionTable)
{
string Base64EncodeDelegate(XPath2Context context, IContextProvider provider, object[] args)
{
string value = CoreFuncs.CastToStringExactOne(context, args[0]);
Encoding encoding = args.Length == 2 ? ParseEncodingFromArg(context, args[1]) : Encoding.UTF8;

try
{
return Convert.ToBase64String(encoding.GetBytes(value));
}
catch (Exception ex)
{
throw new XPath2Exception("InvalidFormat", ex);
}
}

// base64encode with default UTF-8 encoding
functionTable.Add(XmlReservedNs.NsXQueryFunc, "base64encode", 1, XPath2ResultType.String, Base64EncodeDelegate);

// base64encode with specified encoding
functionTable.Add(XmlReservedNs.NsXQueryFunc, "base64encode", 2, XPath2ResultType.String, Base64EncodeDelegate);
}

/// <summary>
/// Extend the XPath2 FunctionTable with 'base64decode' function to decode a base64 string to a string.
/// </summary>
/// <param name="functionTable">The function table.</param>
public static void AddBase64Decode(this FunctionTable functionTable)
{
string Base64DecodeDelegate(XPath2Context context, IContextProvider provider, object[] args)
{
bool fixPadding = true;
Encoding encoding = Encoding.UTF8;
string value = CoreFuncs.CastToStringExactOne(context, args[0]);

if (args.Length == 2)
{
try
{
// first try to cast to bool
fixPadding = CoreFuncs.GetBooleanValue(args[1]);
}
catch (Exception)
{
// else parse as encoding
encoding = ParseEncodingFromArg(context, args[1]);
}
}

if (args.Length == 3)
{
encoding = ParseEncodingFromArg(context, args[1]);
fixPadding = CoreFuncs.GetBooleanValue(args[2]);
}

if (fixPadding)
{
value = value.Trim('=');
int mod = value.Length % 4;
if (mod != 0)
{
value = string.Concat(value, new string('=', 4 - mod));
}
}

try
{
return encoding.GetString(Convert.FromBase64String(value));
}
catch (Exception ex)
{
throw new XPath2Exception("InvalidFormat", ex.Message);
}
}

// base64decode with default UTF-8 encoding
functionTable.Add(XmlReservedNs.NsXQueryFunc, "base64decode", 1, XPath2ResultType.String, Base64DecodeDelegate);

// base64decode with specified encoding (string) or fixPadding (bool)
functionTable.Add(XmlReservedNs.NsXQueryFunc, "base64decode", 2, XPath2ResultType.String, Base64DecodeDelegate);

// base64decode with specified encoding (string) and fixPadding (bool)
functionTable.Add(XmlReservedNs.NsXQueryFunc, "base64decode", 3, XPath2ResultType.String, Base64DecodeDelegate);
}

#region private helper methods
private static Encoding ParseEncodingFromArg(XPath2Context context, object arg)
{
string name = CoreFuncs.CastToStringOptional(context, arg);

try
{
return Encoding.GetEncoding(name);
}
catch (Exception)
{
throw new XPath2Exception("FORG0001", Properties.Resources.FORG0001, name, "Encoding.GetEncoding()");
}
}
#endregion
}
}
22 changes: 22 additions & 0 deletions src/XPath2.Extensions.Core/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Reflection;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("XPath2.Extensions.Core")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("XPath2.Extensions.Core")]
[assembly: AssemblyCopyright("Copyright © Stef Heyenrath 2021-2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("A2279454-fc88-44fe-b037-b514ab23c2b0")]
72 changes: 72 additions & 0 deletions src/XPath2.Extensions.Core/XPath2.Extensions.Core.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<!--<Version>1.1.0.0</Version>-->
<Description>Non-official Newtonsoft.Json extensions for XPath2.dll (generate-id, base64encode and base64decode)</Description>
<Copyright>Stef Heyenrath</Copyright>
<AssemblyTitle>Non-official Newtonsoft.Json extensions for XPath2.dll</AssemblyTitle>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net35;net40;net452;netstandard2.0;netstandard2.1</TargetFrameworks>
<AssemblyName>XPath2.Extensions.Core</AssemblyName>
<PackageId>XPath2.Extensions.Core</PackageId>
<PackageTags>XPath;XPath2;XPath2.0;Xml;W3C;XQuery;XQTS;Extensions</PackageTags>
<PackageReleaseNotes>See ReleaseNotes.md</PackageReleaseNotes>
<PackageIconUrl>https://raw.githubusercontent.com/StefH/XPath2.Net/master/resources/XPath2ex-icon-64x64.png</PackageIconUrl>
<PackageProjectUrl>https://github.com/StefH/XPath2.Net</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<GenerateAssemblyTitleAttribute>false</GenerateAssemblyTitleAttribute>
<GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
<RootNamespace>Wmhelp.XPath2.Extensions.Core</RootNamespace>
<DebugType>full</DebugType>
<AssemblyOriginatorKeyFile>../XPath2.snk</AssemblyOriginatorKeyFile>
<SignAssembly>true</SignAssembly>
<ProjectGuid>{A1326CF6-DEC2-4538-B46E-B045D3F7AFC3}</ProjectGuid>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
</PropertyGroup>

<PropertyGroup Condition=" '$(buildType)' == 'azure-pipelines-ci' ">
<TargetFrameworks>net40;net452;netstandard2.0;netstandard2.1</TargetFrameworks>
</PropertyGroup>

<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
</ItemGroup>

<!-- https://github.com/Microsoft/msbuild/issues/1333 -->
<PropertyGroup Condition=" '$(TargetFramework)' == 'net35' ">
<!-- <FrameworkPathOverride>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v3.5\Profile\Client</FrameworkPathOverride> -->
<FrameworkPathOverride>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2</FrameworkPathOverride>
</PropertyGroup>

<PropertyGroup Condition=" '$(TargetFramework)' == 'net40' ">
<FrameworkPathOverride>C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2</FrameworkPathOverride>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\XPath2\XPath2.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="JetBrains.Annotations" Version="10.4.0" PrivateAssets="All" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'net35' ">
<Reference Include="System" />
<Reference Include="System.Xml" />
<PackageReference Include="Newtonsoft.Json" Version="6.0.8" />
</ItemGroup>

<ItemGroup Condition=" '$(TargetFramework)' == 'net40' or '$(TargetFramework)' == 'net452' ">
<Reference Include="System" />
<Reference Include="System.Xml" />
</ItemGroup>

</Project>
49 changes: 49 additions & 0 deletions src/XPath2.Extensions.NewtonsoftJson/FunctionTableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System.Xml;
using System.Xml.XPath;
using JetBrains.Annotations;
using Wmhelp.XPath2.MS;

namespace Wmhelp.XPath2.Extensions
{
public static class FunctionTableExtensions
{
/// <summary>
/// Extend the XPath2 FunctionTable with:
/// - json-to-xml
/// - json-to-xmlstring
/// </summary>
/// <param name="functionTable">The function table.</param>
public static void AddJsonToXml([NotNull] this FunctionTable functionTable)
{
XPathNavigator JsonStringToXPathNavigator(XPath2Context context, IContextProvider provider, object[] args)
{
string value = CoreFuncs.CastToStringExactOne(context, args[0]);
string root = args.Length == 2 ? CoreFuncs.CastToStringOptional(context, args[1]) : null;

string dynamicRootObject;
XmlNode xmlDoc = Json2XmlUtils.Json2XmlNode(value, out dynamicRootObject, root);

return xmlDoc?.CreateNavigator();
}

string JsonStringToXmlString(XPath2Context context, IContextProvider provider, object[] args)
{
var nav = JsonStringToXPathNavigator(context, provider, args);

return nav != null ? nav.InnerXml : string.Empty;
}

// json-to-xml with no root element
functionTable.Add(XmlReservedNs.NsXQueryFunc, "json-to-xml", 1, XPath2ResultType.Navigator, JsonStringToXPathNavigator);

// json-to-xml with specified root element
functionTable.Add(XmlReservedNs.NsXQueryFunc, "json-to-xml", 2, XPath2ResultType.Navigator, JsonStringToXPathNavigator);

// json-to-xmlstring with no root element
functionTable.Add(XmlReservedNs.NsXQueryFunc, "json-to-xmlstring", 1, XPath2ResultType.String, JsonStringToXmlString);

// json-to-xmlstring with specified root element
functionTable.Add(XmlReservedNs.NsXQueryFunc, "json-to-xmlstring", 2, XPath2ResultType.String, JsonStringToXmlString);
}
}
}
22 changes: 22 additions & 0 deletions src/XPath2.Extensions.NewtonsoftJson/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Reflection;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("XPath2.Extensions.NewtonsoftJson")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("XPath2.Extensions.NewtonsoftJson")]
[assembly: AssemblyCopyright("Copyright © Stef Heyenrath 2021-2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("12279454-fc88-44fe-b037-b514ab23c2bf")]
Loading