crs4 / hl7apy

Python library to parse, create and handle HL7 v2 messages.
http://crs4.github.io/hl7apy/
MIT License
224 stars 88 forks source link

HL7 parsing (with TOLERANT) does not handle hl7 elements outside hl7 version spec. #57

Open mikkelcp1 opened 4 years ago

mikkelcp1 commented 4 years ago

branch: develop

While reading Validation doc (http://crs4.github.io/hl7apy/tutorial/index.html#validation)

Moreover, when using STRICT validation it is not possible to instantiate an unknown element. In TOLERANT mode, the library does not perform the checks listed above

It appears that TOLERANT validation, should allow for non-structured children (unknown element) on instantiation of a Message, where a further call to validate() should return False.

While parsing a message with more sub-component(s) than the spec. allows for, the following Exception is thrown (see code block). The component OBR-32-1 = "PATH1&TestUser&Pathologist&&&Pathologist&&&HNAM_USERID&&USERID" and contains OBR-32-1-11 which doesn't exist in the 2.3 spec.

It would be great if TOLERANT would support parsing of unknown elements (outside the hl7 version spec.).

        msg = hl7apy.parser.parse_message(hl7MsgRaw, validation_level=VALIDATION_LEVEL.TOLERANT, find_groups=False, message_profile=None, report_file=None,
>                 force_validation=False)

File "C:\git\ccns-document-processor\tests\unit\test_Hl7Message.py", line 998

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
File "C:\ProgramData\Anaconda3\envs\ccns\lib\site-packages\hl7apy\parser.py", line 88
in parse_message
    children = parse_segments(message, m.version, encoding_chars, validation_level, m.reference, find_groups)
File "C:\ProgramData\Anaconda3\envs\ccns\lib\site-packages\hl7apy\parser.py", line 152
in parse_segments
    segment = parse_segment(s.strip(), version, encoding_chars, validation_level)
File "C:\ProgramData\Anaconda3\envs\ccns\lib\site-packages\hl7apy\parser.py", line 241
in parse_segment
    segment.structure_by_name, segment.allow_infinite_children)
File "C:\ProgramData\Anaconda3\envs\ccns\lib\site-packages\hl7apy\parser.py", line 315
in parse_fields
    reference, force_varies))
File "C:\ProgramData\Anaconda3\envs\ccns\lib\site-packages\hl7apy\parser.py", line 389
in parse_field
    field.structure_by_name)
File "C:\ProgramData\Anaconda3\envs\ccns\lib\site-packages\hl7apy\parser.py", line 462
in parse_components
    version, encoding_chars, validation_level, reference))
File "C:\ProgramData\Anaconda3\envs\ccns\lib\site-packages\hl7apy\parser.py", line 522
in parse_component
    children = parse_subcomponents(text, component.datatype, version, encoding_chars, validation_level)
File "C:\ProgramData\Anaconda3\envs\ccns\lib\site-packages\hl7apy\parser.py", line 587
in parse_subcomponents
    version, validation_level))
File "C:\ProgramData\Anaconda3\envs\ccns\lib\site-packages\hl7apy\parser.py", line 620
in parse_subcomponent
    validation_level=validation_level)
File "C:\ProgramData\Anaconda3\envs\ccns\lib\site-packages\hl7apy\core.py", line 1120
in __init__
    version, validation_level, traversal_parent)
File "C:\ProgramData\Anaconda3\envs\ccns\lib\site-packages\hl7apy\core.py", line 1046
in __init__
    validation_level, traversal_parent)
File "C:\ProgramData\Anaconda3\envs\ccns\lib\site-packages\hl7apy\core.py", line 642
in __init__
    self._find_structure(reference)
File "C:\ProgramData\Anaconda3\envs\ccns\lib\site-packages\hl7apy\core.py", line 1069
in _find_structure
    structure = ElementFinder.get_structure(self, reference)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

element = <SubComponent CN_SIMPLE_11>, reference = None

    @staticmethod
    def get_structure(element, reference=None):
        """
        Get the element structure

        :type element: :class:`Element <hl7apy.core.Element>`
        :param element: element having the given reference structure

        :param reference: the element structure from :func:`load_reference <hl7apy.load_reference>` or from a
            message profile

        :return: a dictionary containing the structure data
        """
        if reference is None:
            try:
                reference = load_reference(element.name, element.classname, element.version)
            except (ChildNotFound, KeyError):
>               raise InvalidName(element.classname, element.name)
E               hl7apy.exceptions.InvalidName: Invalid name for SubComponent: CN_SIMPLE_11

File "C:\ProgramData\Anaconda3\envs\ccns\lib\site-packages\hl7apy\core.py", line 552
InvalidName