发布新帖

検索

讨论 (1)1
登录或注册以继续
文章
· 二月 9, 2023 阅读大约需 3 分钟

Schematron XML documents validation using Python

Schematron is a rule-based validation language for making assertions about the presence or absence of certain patterns in XML documents. A schematron refers to a collection of one or more rules containing tests. Schematrons are written in a form of XML, making them relatively easy for everyone, even non-programmers, to inspect, understand, and write

Essentially, a Schematron performs two actions in sequence:

Find context nodes of interest in the document. A "context node" can be an element of a particular type or a specific element at a particular place in the document, an attribute, or an attribute value. For example, suppose you want to check if the sum of the <Percent> elements within each context node is 100%. In this case, the context node would be the <Total> element. For each of those nodes of interest, it checks whether a specific statement is true or false. For example, you might have a rule written to answer the question "Is the sum total 100%?"

The ideal resource to look for more detail on the subject would be: https://www.schematron.com/. What matters to us is that we can validate our XML document based on a Schematron definition. For this, it must be taken into account that there are multiple open source projects with Schematron implementations for XSLT. One of the most interesting is available at https://github.com/schxslt/schxslt.git.

This article aims to leverage the Python capabilities available in InterSystems IRIS (for Health) or HealthShare (Health Connect).

For this we need an instance of InterSystems IRIS or HealthShare Health Connect. For our example we will use a container with the latest community edition of InterSystems IRIS for Health. We have to start the instance by publishing the default ports and mapping the current directory to the durable folder in the container.

$ docker run --name iris4health -d --publish 51773:51773 --publish 52773:52773  --volume $(pwd):/durable containers.intersystems.com/intersystems/irishealth-community:2022.3.0.589.0

Now that we have our instance running we can start a console in the container.

$ docker exec -it <containerID> bash

Now we can focus on the Python module. We will use lxml. This is a Python binding for the C libraries libxml2 and libxslt. It is unique as it combines the speed and completeness of the XML functions of these libraries with the simplicity of a native Python API, mostly compatible with the familiar ElementTree API. For more information about lxml https://lxml.de/index.html

Assuming that the pip3 package manager (and of course Python 3) is already installed on the instance, the appropriate module will need to be installed.

$ pip3 install --target /usr/irissys/mgr/python lxml

The example method that we will use will be coded in Python and will be in charge of parsing and validating the schematron rules. The code of the class that we will use is the following:

Class dc.schematron Extends %RegisteredObject
{

/// Description
ClassMethod simpleTest() [ Language = python ]
{
        from lxml import isoschematron
        from lxml import etree

        print("Validating File...\n")

        # def runsch(rulesFile, xmlFile):
        #open files
        rules = open('/durable/test-schema.sch', 'rb') # Schematron schema
        XMLhere = open('/durable/test-file.xml', 'rb') # XML file to check 
        #Parse schema
        sct_doc= etree.parse(rules)
        schematron=isoschematron.Schematron(sct_doc, store_report=True)

        #Parse XML
        doc = etree.parse(XMLhere)

        #Validate against schema
        validationResult = schematron.validate(doc)
        report = schematron._validation_report
    
        #Check result
        if validationResult:
            print("passed")
        else:
            print("failed")
            print(report)
}

}

The truth is that it is a fairly simple method. It opens 2 files – the file with the rules (schematron) and an example file. The rule is to check if the sum of the <Percent> elements within each <Total> node is 100%. To execute it, you will have to launch the following command from the console:

d ##class(dc.schematron).simpleTest()

The result will be presented in the console. The same logic can be used in an interop production.

The source code containing all the elements is available here

讨论 (0)1
登录或注册以继续
InterSystems 官方
· 二月 8, 2023

Starting developer preview #1 for InterSystems IRIS, IRIS for Health, & HealthShare Health Connect 2023.1

InterSystems announces its first developer preview, as part of the developer preview program for 2023.1 release. Many updates and enhancements have been added in 2023.1 and there are also brand-new capabilities, such as production-ready support for Columnar Storage, ability to use Bulk FHIR, and support to MacOS 13 Ventura. Some of these features or improvements may not be available in this current developer preview.

Future preview releases are expected to be updated biweekly and we will add features as they are ready. Please share your feedback through the Developer Community so we can build a better product together.

Initial documentation can be found at these links below. They will be updated over the next few weeks until launch is officially announced (General Availability - GA):

In addition, check out this link for upgrade information related to this release.

As usual, Extended Maintenance (EM) releases come with classic installation packages for all supported platforms, as well as container images in Docker container format.  For a complete list, refer to the Supported Platforms document.

Installation packages and preview keys are available from the WRC's preview download site or through the evaluation services website (use the flag "Show Preview Software" to get access to the 2023.1).

Container images for both Enterprise and Community Editions of InterSystems IRIS and IRIS for Health and all corresponding components are available from the new InterSystems Container Registry web interface. For additional information about docker commands, please see this post:: Announcing the InterSystems Container Registry web user interface.

The build number for this developer preview release is 2023.1.0.185.0.

For a full list of the available images, please refer to the ICR documentation. Alternatively, tarball versions of all container images are available via the WRC's preview download site.

讨论 (0)3
登录或注册以继续
文章
· 二月 7, 2023 阅读大约需 5 分钟

IRIS quick query service idea sharing

Hello, friends who are developing IRIS. I recently participated in the InterSystems Developer Tools Contest. This time, I made a tool based on the idea described in an article I published earlier as a template for quick query of messages. Currently, you only need to establish entity classes in IRIS, Then record the message corresponding to the entity class in the specified lookup table, and all the key fields generated in the message can be inverted indexed (the concept in ElasticSearch), which is convenient for quick query. The following is the design idea of my program.

background

In China, as an integrated platform manufacturer, most of the things that hospitals do when they jointly debug with other systems are not to develop code but to check messages. Let me first demonstrate the IRIS message checking method I am currently using

Example 1:

You need to see [个人信息注册服务]

I just need to enter [个人信息注册服务] in the box and press Enter

 

 

Click View Message to display the contents of the message, as shown in the figure:

 

 

Click [View Process] to display the IRIS message visualization page, as shown in the figure

 

 

Example 2:

You need to query which services are called by the patient whose ID is [2874621] on the integrated platform

I just need to select [Patient ID] from the drop-down list, then enter [2874621],  Enter:

This is how we can intuitively query the specified message from the perspective of user needs. IRIS also has this function - message viewer. How is it used? First, we need to know which Production components are used in this message. Second, we need to understand the structure of the entity class used in this message. For example, to check this person's message, I need to enter request. Body. PatientID="2874621" and select the message class. If I need to check multiple services, I also need to select multiple message classes... This article is not about how to use the message viewer. You may as well know it. 

Program analysis and design ideas

    Use of the original message viewer

We first use the [Message Viewer] provided by IRIS to check the personal information registration service with the patient ID of [2874621], as shown in the figure:

 

    Select the time and enter the conditions shown in the figure to retrieve. The steps seem quite simple, but there are two prerequisites. First, I need to know which message class corresponds to each service. Second, I know which field corresponds to the patient ID in this message class, and this field cannot be in the loop (it seems to say three conditions~haha). How to deal with it is in front of us

 

    SQL  analysis

Use the [Display Query] function provided by IRIS (see my other article on how to turn it on https://cn.community.intersystems.com/node/525741 ),As shown in the figure

 

 

Find a place to format it

 

You can see three points from this SQL

1The table of IRIS message records isEns.MessageHeader

2IRIS saves messages by creating a table for the entity itself, such as the above example:【BKIP_PatientInfo_MSG.PatientInfoRegister

3head.MessageBodyId = BKIP_PatientInfo_MSG.PatientInfoRegister.%ID

Through these three items, we can get the information of the following figure

          If we process SQL in the way shown in the above figure, and then reflect it on the page for users to choose; The patient ID is also selected or entered by the user; This is really an intuitive solution. However, efficiency. When the user selects the time, the above message viewer first finds two IDs so that the query can find between these two primary key IDs, which increases efficiency. We can certainly use it. So is it necessary? If we remove it, we must slow down? This is one of them. Second, if the patient ID is in the loop, even in the loop... the message viewer seems to have no way (of course, please accept my knee if there is a boss who can solve it).

    Problems to be solved

  1. Comparison table, service and message comparison table
  2. How to query fields in the loop as keywords

The first problem is the solution. Create a new table to maintain the relationship between the service and the message class. The second problem is that we need to look at the table Ens.MessageHeader:

 

 

I don’t seem to see anything...

You can see this picture

The red box in the figure is the same. At the same time, we enter the message visualization, as shown in the figure

Can we say that the session ID is the message representing the service? We want to check the message of the specified person of the specified service, which can be understood as checking the session ID, that is, the session ID. Let’s change our thinking. If I traverse the patient ID in the loop and store it in a table, I have sessionID, patient ID, and service name for the data in this row. When I want to check the personal information registration service with the patient ID of [2874621] and get the sessionID, I directly jump to the visual tracking. If I change the patient ID into the doctor’s order ID, the same is true for other key fields. Is the problem solved?

Program design (idea)

Create a new index table field as SessionID, service name, attribute name, attribute value and creation time, as shown in the figure

 

 

    Then, each time the service is called, take out the attribute name, attribute value and SessionID we need and store them in this table, as shown in the figure

When we query on the page, we only need to write the SQL as shown in the figure. The ellipsis represents the condition after and

The following REST interface and front-end page are here [omitted]. You can refer to the ideas provided in my other article to write and provide the Restful interface

(https://cn.community.intersystems.com/node/525561 )

summary      

In general, our idea is that we should reduce the original data volume and maintain the original problem of multiple loops in multiple rows of data in a single table. In this way, the original multi-table joint query is changed into a single-table query. This speed is not fast to fly? At present, we only share ideas. I believe that we must have our own way of program design. I will not show too much for the time being. See here, please give me a compliment!!

 

      Of course, there are still many things that need to be optimized for the tool to make it more convenient, but at present I use it as a demo tool. If the project has a good response, I would like to continue to optimize it. If you think it is good, please vote for me:https://openexchange.intersystems.com/package/message-key-query

1 Comment
讨论 (1)1
登录或注册以继续
问题
· 二月 6, 2023

HealthConnect : queue messages and then send by message type

Hi Community,

I need to find a good way to queue messages and then send them later by document type where document type is an HL7 attribute of the message.

Any suggestions?

Thanks

Regards

Mike

2 Comments
讨论 (2)2
登录或注册以继续