Skip to content

Commit

Permalink
Add a new filter - splitDataBySegments (#344)
Browse files Browse the repository at this point in the history
  • Loading branch information
yankunhuang-pku authored Dec 21, 2021
1 parent 2bb197d commit fc949c7
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
// -------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Health.Fhir.Liquid.Converter.Models.Hl7v2;
using Microsoft.Health.Fhir.Liquid.Converter.Parsers;
Expand Down Expand Up @@ -116,6 +117,65 @@ public void GivenAnHl7v2Data_WhenHasSegments_CorrectResultShouldBeReturned()
Assert.Throws<NullReferenceException>(() => Filters.HasSegments(new Hl7v2Data(), null));
}

[Fact]
public void GivenAnHl7v2Data_WhenSplitDataBySegments_CorrectResultShouldBeReturned()
{
List<Hl7v2Data> splitDataByOrc = Filters.SplitDataBySegments(TestData, "ORC");
Assert.Equal(4, splitDataByOrc.Count);
Assert.Equal(3, splitDataByOrc[0].Meta.Count);
Assert.Equal(7, splitDataByOrc[1].Meta.Count);
Assert.Equal(2, splitDataByOrc[2].Meta.Count);
Assert.Equal(2, splitDataByOrc[3].Meta.Count);
Assert.Equal(3, splitDataByOrc[0].Data.Count);
Assert.Equal(7, splitDataByOrc[1].Data.Count);
Assert.Equal(2, splitDataByOrc[2].Data.Count);
Assert.Equal(2, splitDataByOrc[3].Data.Count);
Assert.Equal("MSH", splitDataByOrc[0].Meta[0]);
Assert.Equal("ORC", splitDataByOrc[1].Meta[0]);
string expectedOrcValue = @"ORC|RE|4422^NIST-AA-IZ-2|13696^NIST-AA-IZ-2|||||||7824^Jackson^Lily^Suzanne^^^^^NIST-PI-1^L^^^PRN||654^Thomas^Wilma^Elizabeth^^^^^NIST-PI-1^L^^^MD|||||NISTEHRFAC^NISTEHRFacility^HL70362|";
Assert.Equal(expectedOrcValue, splitDataByOrc[1].Data[0].Value);

List<Hl7v2Data> splitDataByMsh = Filters.SplitDataBySegments(TestData, "MSH");
Assert.Equal(2, splitDataByMsh.Count);
Assert.Empty(splitDataByMsh[0].Meta);
Assert.Empty(splitDataByMsh[0].Data);
Assert.Equal(14, splitDataByMsh[1].Meta.Count);
Assert.Equal(14, splitDataByMsh[1].Data.Count);

List<Hl7v2Data> splitData = Filters.SplitDataBySegments(TestData, "PID|OBX");
Assert.Equal(6, splitData.Count);
Assert.Single(splitData[0].Meta);
Assert.Equal(5, splitData[1].Meta.Count);
Assert.Single(splitData[2].Meta);
Assert.Single(splitData[3].Meta);
Assert.Single(splitData[4].Meta);
Assert.Equal(5, splitData[5].Meta.Count);
Assert.Single(splitData[0].Data);
Assert.Equal(5, splitData[1].Data.Count);
Assert.Single(splitData[2].Data);
Assert.Single(splitData[3].Data);
Assert.Single(splitData[4].Data);
Assert.Equal(5, splitData[5].Data.Count);
Assert.Equal("MSH", splitData[0].Meta[0]);
Assert.Equal("PID", splitData[1].Meta[0]);
Assert.Equal("OBX", splitData[2].Meta[0]);
Assert.Equal(@"OBX|1|CE|30963-3^Vaccine Funding Source^LN|1|PHC70^Private^CDCPHINVS||||||F|||20150624", splitData[2].Data[0].Value);

splitData = Filters.SplitDataBySegments(TestData, "PID|||OBX|KKK|");
Assert.Equal(6, splitData.Count);
Assert.Equal("MSH", splitData[0].Meta[0]);
Assert.Equal("PID", splitData[1].Meta[0]);
Assert.Equal("OBX", splitData[2].Meta[0]);

// If separators are not in the data or empty, a data list containing only the original data will be returned.
Assert.StrictEqual(TestData, Filters.SplitDataBySegments(TestData, string.Empty)[0]);
Assert.StrictEqual(TestData, Filters.SplitDataBySegments(TestData, "PV1")[0]);

// Hl7v2Data and separators could not be null. If one of them is null, NullReferenceException will be thrown.
Assert.Throws<NullReferenceException>(() => Filters.SplitDataBySegments(null, "ORC"));
Assert.Throws<NullReferenceException>(() => Filters.SplitDataBySegments(TestData, null));
}

private static Hl7v2Data LoadTestData()
{
var parser = new Hl7v2DataParser();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// -------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// -------------------------------------------------------------------------------------------------

using System;
using Microsoft.Health.Fhir.Liquid.Converter.Utilities;
using Xunit;

namespace Microsoft.Health.Fhir.Liquid.Converter.UnitTests.Utilities
{
public class Hl7v2DataUtilityTests
{
[Fact]
public void GivenValidMessage_WhenSplitMessageToSegments_CorrectResultShouldBeReturned()
{
string[] testMessage =
{
"\r\nMSH|^~\\&|test\r\nPID|test\r\n\r\nPD1|test\r\nPD1|test\r\n",
"\rMSH|^~\\&|test\rPID|test\r\rPD1|test\rPD1|test\r",
"\nMSH|^~\\&|test\nPID|test\n\nPD1|test\nPD1|test\n",
"\nMSH|^~\\&|test\r\nPID|test\r\r\nPD1|test\r\n\nPD1|test\r\n",
};

foreach (string message in testMessage)
{
string[] segments = Hl7v2DataUtility.SplitMessageToSegments(message);
Assert.Equal(4, segments.Length);
Assert.Equal("MSH|^~\\&|test", segments[0]);
Assert.Equal("PID|test", segments[1]);
Assert.Equal("PD1|test", segments[2]);
Assert.Equal("PD1|test", segments[3]);
}

Assert.Empty(Hl7v2DataUtility.SplitMessageToSegments(string.Empty));

// message could not be null
Assert.Throws<NullReferenceException>(() => Hl7v2DataUtility.SplitMessageToSegments(null));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,5 +128,37 @@ private static Dictionary<string, List<Hl7v2Segment>> GetSegmentListsInternal(Hl

return result;
}

public static List<Hl7v2Data> SplitDataBySegments(Hl7v2Data hl7v2Data, string segmentIdSeparators)
{
var results = new List<Hl7v2Data>();
var result = new Hl7v2Data();
var segmentIds = new HashSet<string>(segmentIdSeparators.Split(@"|", StringSplitOptions.RemoveEmptyEntries));

if (segmentIdSeparators == string.Empty || !segmentIds.Intersect(hl7v2Data.Meta).Any())
{
results.Add(hl7v2Data);
return results;
}

for (var i = 0; i < hl7v2Data.Meta.Count; ++i)
{
if (segmentIds.Contains(hl7v2Data.Meta[i]))
{
results.Add(result);
result = new Hl7v2Data();
}

result.Meta.Add(hl7v2Data.Meta[i]);
result.Data.Add(hl7v2Data.Data[i]);
}

if (result.Meta.Count > 0)
{
results.Add(result);
}

return results;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@
using Microsoft.Health.Fhir.Liquid.Converter.InputProcessors;
using Microsoft.Health.Fhir.Liquid.Converter.Models;
using Microsoft.Health.Fhir.Liquid.Converter.Models.Hl7v2;
using Microsoft.Health.Fhir.Liquid.Converter.Utilities;
using Microsoft.Health.Fhir.Liquid.Converter.Validators;

namespace Microsoft.Health.Fhir.Liquid.Converter.Parsers
{
public class Hl7v2DataParser : IDataParser
{
private static readonly Hl7v2DataValidator Validator = new Hl7v2DataValidator();
private static readonly string[] SegmentSeparators = { "\r\n", "\r", "\n" };

public object Parse(string message)
{
Expand All @@ -30,7 +30,7 @@ public object Parse(string message)
{
var result = new Hl7v2Data(message);

var segments = message.Split(SegmentSeparators, StringSplitOptions.RemoveEmptyEntries);
var segments = Hl7v2DataUtility.SplitMessageToSegments(message);
Validator.ValidateMessageHeader(segments[0]);
var encodingCharacters = ParseHl7v2EncodingCharacters(segments[0]);
result.EncodingCharacters = encodingCharacters;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// -------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
// -------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;

namespace Microsoft.Health.Fhir.Liquid.Converter.Utilities
{
public static class Hl7v2DataUtility
{
private static readonly string[] SegmentSeparators = { "\r\n", "\r", "\n" };

public static string[] SplitMessageToSegments(string message)
{
var segments = message.Split(SegmentSeparators, StringSplitOptions.RemoveEmptyEntries);
return segments;
}
}
}

0 comments on commit fc949c7

Please sign in to comment.