Отдельно на этом сайте я получил отличную помощь REGEX (спасибо Андреас!), Чтобы найти эти поля вручную. Но я хотел сохранить 100% исходных данных аварийных служб, а не редактировать поле в соответствии с NEMSIS XSD как обходной путь REGEX с субъективным редактированием вручную.
Соответственно, я пытаюсь взять любой элемент E09_05 или E09_08 (Главная жалоба и Вторичная жалоба, согласно словарю данных NEMSIS), то есть string-length()
> 50 символов и concat()
его в начало Повествование или поле E13_01. Затем я бы заменил эти длинные жалобы на простой <E09_05>See Narrative E13_01 for Chief Complaint</E09_05>
(то же самое для E09_08, вместо этого просто «Вторичная жалоба»).
Каждый отдельный тег, текст и атрибут, в противном случае в souce XML, должен быть пропущен без изменений (см. <xsl:template match="@*|node()">
в конце скрипта). Единственные изменения заключались в том, чтобы переместить поля длинных жалоб в соответствующие описания для каждого <Record>
.
Коллеги помогли мне разработать этот сценарий. Они клянутся, что это работает на их системе, но я не могу заставить это работать на моей. Я пробовал несколько движков xslt, включая msxsl.exe (требуется в нашей среде), но также - просто пытался заставить что-то работать и исключить проблему с процессором - тот, что в Notepad ++ XML Tools, тот, что в XML Редактор копирования, а также бесплатный онлайн-сервис на freeformatter.com. В конце, тем не менее, msxsl должен быть тем, который работает (не мой выбор ... это дело правительства).
Как я прокомментировал ниже в исходном и XSLT-файлах, я попробовал относительный XPath с потомком //
или абсолютным путем и т. Д. c. Не повезло.
Источник XML (значительно сокращен для краткости):
<?xml version="1.0" encoding="UTF-8"?>
<EMSDataSet xmlns="http://www.nemsis.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.nemsis.org http://www.nemsis.org/media/XSD/EMSDataSet.xsd">
<Header>
<!-- SOME STUFF -->
<Record>
<!-- LOTS OF STUFF -->
<E08>
<E08_08>2016</E08_08>
<E08_10 Lat="42.63" Long="70.68" />
</E08>
<E09>
<E09_04>-5</E09_04>
<!-- XSLT SHOULD HIT ON THIS AS IT'S AN E09_05 WITH > 50 CHAR string-length() -->
<E09_05>this one is too long Non-Emergency - PT IS BEING DISCHARGED FROM AGH AFTER BEING ADMITTED FOR FAILURE TO THRIVE AND ALCOHOL WITHDRAWAL</E09_05>
<E09_11>-5</E09_11>
</E09>
<E10>
<E10_01>-5</E10_01>
<E10_03>-5</E10_03>
</E10>
<!-- SOME IN BETWEEN STUFF -->
<E13>
<!-- xslt SHOULD concat() THE OVER-LONG E09_05 TEXT HERE AT THE BEGINNING -->
<E13_01>A8 DISPATCHED TO AGH FOR A 66 Y/O MALE PT BEING DISCHARGED FROM AGH WITH UNSTEADY GAIT --DELETED FOR BREVITY --**A8 CLEAR, WITHOUT INCIDENT**. </E13_01>
</E13>
<!-- REST OF THIS DELETED TO SAVE SPACE -->
</Record>
<Record>
<!-- STUFF DELETED FOR BREVITY - AND THIS E09_05 BELOW SHOULD BE IGNORED BY THE XSLT AND PASSED THROUGH AS IS -->
<E08>
<E08_08>2016</E08_08>
<E08_10 Lat="42.77" Long="70.61" />
</E08>
<E09>
<E09_04>-5</E09_04>
<E09_05>this length is okay</E09_05>
<E09_11>-5</E09_11>
</E09>
<E10>
<E10_01>-5</E10_01>
<E10_03>-5</E10_03>
</E10>
<!-- DELETED FOR BREVITY -->
<E13>
<E13_01>CC= Working as a P/B truck during major snowstorm, on scene, found pt c/o having a syncopal episode. HXPI= Pt's girlfriend stated that the pt had been outside shoveling snow for approx 1 hour. --DELETED FOR BREVITY OF EXAMPLE </E13_01>
</E13>
</Record>
</Header>
</EMSDataSet>
Вот XSLT - единственное, что работает, это первый шаблон, который сохраняет пустые теги как пустые, не пары без содержимого (семантически эквивалентные, да, но NEMSIS XSD не будет принимать парные теги, только пустые), а также последний шаблон, который проходит через весь исходный контент.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml"/>
<xsl:strip-space elements="*"/>
<!-- THIS TEMPLATE I FOUND IN A WEB SEARCH TO KEEP EMPTY TAGS AS EMPTY TAGS, WHICH I KNOW ARE SEMANTICALLY EQUIVALENT, BUT THE NEMSIS.XSD WILL NOT ACCEPT PAIRED TAGS, ONLY EMPTY ONES FOR CERTAIN TAGS -->
<xsl:template match="*[not(comment() | processing-instruction() | *)][normalize-space(text()) = '']">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:for-each select="@* | namespace::*">
<xsl:copy/>
</xsl:for-each>
</xsl:element>
</xsl:template>
<!-- REPLACE E09_05 FIELDS THAT ARE > 50 CHARACTERS WITH THIS "SEE NARRATIVE ..." REPLACEMENT -->
<xsl:template match="E09_05[string-length(.) > 50]">
<E09_05>See narrative for Chief Complaint</E09_05>
</xsl:template>
<!-- DO THE SAME THING HERE FOR E09_08, I TRIED A FEW DIFFERENT PATH OPTIONS TO GET IT TO "HIT" AND NONE WOULD WORK, E.G., DESCENDANT AXIS //, ABSOLUTE PATH, ETC. -->
<xsl:template match="E09_08[string-length(.) > 50]">
<E09_08>See narrative for Secondary Complaint</E09_08>
</xsl:template>
<!-- CONCAT THE OVERLONG E09_05 AND/OR E09_08 TEXT TO THE BEGINNING OF THIS E13_01 FIELD -->
<xsl:template match="E13_01/text()">
<xsl:copy/>
<xsl:value-of select="concat('ChiefComplaint:',' ', ../../../E09/E09_05[string-length(.) > 50])"/>
<xsl:value-of select="concat('SecondaryComplaint:',' ', ../../../E09/E09_08[string-length(.) > 50])"/>
</xsl:template>
<!-- identity transform - pass through all other content complete and untouched/unchanged -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>