XSLT не будет выбирать узел для простого сценария перемещения и замены текста () - PullRequest
0 голосов
/ 02 февраля 2020

Отдельно на этом сайте я получил отличную помощь 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>

1 Ответ

0 голосов
/ 02 февраля 2020

Это просто еще один вариант FAQ для XSLT / XPath 1.0 о том, как сопоставлять и / или выбирать элементы во входных данных, которые находятся в пространстве имен, для этого вам нужно объявить пространство имен в XSLT с префиксом, который вы используете. можете выбрать, а затем вам нужно использовать этот префикс для определения любых имен элементов в шаблонах сопоставления XSLT и выражениях пути XPath; с некоторой очисткой для использования xsl:copy, чтобы легко гарантировать, что скопированные результирующие элементы сохраняют входное пространство имен и некоторые переменные, чтобы четко идентифицировать элементы, на которые вы хотите сослаться, и вставлять текстовые константы, такие как ChiefComplaint:, только если была слишком длинная запись в итоге вы получите

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:em="http://www.nemsis.org"
    exclude-result-prefixes="em"
    version="1.0">

<xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

<!-- REPLACE E09_05 FIELDS THAT ARE > 50 CHARACTERS WITH THIS "SEE NARRATIVE ..." REPLACEMENT -->
<xsl:template match="em:E09_05[string-length(.) > 50]">
    <xsl:copy>See narrative for Chief Complaint</xsl:copy>
</xsl:template>

<!-- DO THE SAME THING HERE FOR E09_08 -->
<xsl:template match="em: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="em:E13_01/text()">
    <xsl:variable name="e09_05"
      select="ancestor::em:Record/em:E09/em:E09_05[string-length(.) > 50]"/>
    <xsl:if test="$e09_05">
        <xsl:text>ChiefComplaint: </xsl:text>
        <xsl:value-of select="$e09_05"/>
    </xsl:if>
    <xsl:variable name="e09_08"
      select="ancestor::em:Record/em:E09/em:E09_08[string-length(.) > 50]"/>
    <xsl:if test="$e09_08">
        <xsl:text>SecondaryComplaint: </xsl:text>
        <xsl:value-of select="$e09_08"/>
    </xsl:if>
    <xsl:copy/>
</xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/6rexji2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...