XSLT 1.0 Изменить вывод записи на основе параметра одноуровневой записи

У меня есть входящий файл XML со списком участников и иждивенцев, которые мне нужно немного преобразовать, чтобы зависимая информация присоединялась как дочерние записи к информации об участнике, а узел записи участника EN_PLAN_TYPE получает значение на основе от того, сколько иждивенцев есть у участника, а также от их отношений.

ВХОДЯЩИЙ XML

  <EligibilityRecords xmlns="http://Eligibility_LSDD">
    <Eligibility_Detail_Record xmlns="">
      <PT_PARTICIPANT_FILE_IMP_ID>553739837</PT_PARTICIPANT_FILE_IMP_ID>
      <PT_LST_NM>DOE</PT_LST_NM>
      <PT_FRST_NM>JANE</PT_FRST_NM>
      <EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
      <EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
      <EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
      <EN_PLAN_YEAR_STRT_DT>01012017</EN_PLAN_YEAR_STRT_DT>
    </Eligibility_Detail_Record>
    <Eligibility_Detail_Record xmlns="">
        <PT_PARTICIPANT_FILE_IMP_ID>561859010</PT_PARTICIPANT_FILE_IMP_ID>
        <PT_LST_NM>MCLEOD</PT_LST_NM>
        <PT_FRST_NM>CONOR</PT_FRST_NM>
        <EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
        <EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
        <EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
        <EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
    </Eligibility_Detail_Record>
    <Eligibility_Detail_Record xmlns="">
        <PT_PARTICIPANT_FILE_IMP_ID>561859010</PT_PARTICIPANT_FILE_IMP_ID>
        <PT_LST_NM>MCLEOD</PT_LST_NM>
        <PT_FRST_NM>CONOR</PT_FRST_NM>
        <EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
        <EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
        <EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
        <EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
        <DP_PARTICIPANT_FILE_IMP_ID>561859010</DP_PARTICIPANT_FILE_IMP_ID>
        <DP_DEPENDENT_FILE_IMP_ID>SC000018241906</DP_DEPENDENT_FILE_IMP_ID>
        <DP_RELATIONSHIP>Dependent</DP_RELATIONSHIP>
        <DP_LST_NM>MCLEOD</DP_LST_NM>
        <DP_FRST_NM>DUNCAN</DP_FRST_NM>
    </Eligibility_Detail_Record>
    <Eligibility_Detail_Record xmlns="">
      <PT_PARTICIPANT_FILE_IMP_ID>610051908</PT_PARTICIPANT_FILE_IMP_ID>
      <PT_LST_NM>JACKSON</PT_LST_NM>
      <PT_FRST_NM>MICHAEL</PT_FRST_NM>
      <EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
      <EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
      <EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
      <EN_PLAN_YEAR_STRT_DT>01012017</EN_PLAN_YEAR_STRT_DT>
    </Eligibility_Detail_Record>
    <Eligibility_Detail_Record xmlns="">
      <PT_PARTICIPANT_FILE_IMP_ID>610051908</PT_PARTICIPANT_FILE_IMP_ID>
      <PT_LST_NM>JACKSON</PT_LST_NM>
      <PT_FRST_NM>MICHAEL</PT_FRST_NM>
      <EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
      <EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
      <EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
      <EN_PLAN_YEAR_STRT_DT>01012017</EN_PLAN_YEAR_STRT_DT>
      <DP_PARTICIPANT_FILE_IMP_ID>610051908</DP_PARTICIPANT_FILE_IMP_ID>
      <DP_DEPENDENT_FILE_IMP_ID>NC110015202761</DP_DEPENDENT_FILE_IMP_ID>
      <DP_RELATIONSHIP>Spouse</DP_RELATIONSHIP>
      <DP_LST_NM>JACKSON</DP_LST_NM>
      <DP_FRST_NM>MELISSA</DP_FRST_NM>
    </Eligibility_Detail_Record>
    <Eligibility_Detail_Record xmlns="">
      <PT_PARTICIPANT_FILE_IMP_ID>553739837</PT_PARTICIPANT_FILE_IMP_ID>
      <PT_LST_NM>DOE</PT_LST_NM>
      <PT_FRST_NM>JANE</PT_FRST_NM>
      <EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
      <EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
      <EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
      <EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
      <DP_PARTICIPANT_FILE_IMP_ID>553739837</DP_PARTICIPANT_FILE_IMP_ID>
      <DP_DEPENDENT_FILE_IMP_ID>NC110012077673</DP_DEPENDENT_FILE_IMP_ID>
      <DP_RELATIONSHIP>Spouse</DP_RELATIONSHIP>
      <DP_LST_NM>DOE</DP_LST_NM>
      <DP_FRST_NM>JOHN</DP_FRST_NM>
    </Eligibility_Detail_Record>
    <Eligibility_Detail_Record xmlns="">
      <PT_PARTICIPANT_FILE_IMP_ID>553739837</PT_PARTICIPANT_FILE_IMP_ID>
      <PT_LST_NM>DOE</PT_LST_NM>
      <PT_FRST_NM>JANE</PT_FRST_NM>
      <EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
      <EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
      <EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
      <EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
      <DP_PARTICIPANT_FILE_IMP_ID>553739837</DP_PARTICIPANT_FILE_IMP_ID>
      <DP_DEPENDENT_FILE_IMP_ID>NC110012077680</DP_DEPENDENT_FILE_IMP_ID>
      <DP_RELATIONSHIP>Dependent</DP_RELATIONSHIP>
      <DP_LST_NM>DOE</DP_LST_NM>
      <DP_FRST_NM>JIMMY</DP_FRST_NM>
    </Eligibility_Detail_Record>
    <Eligibility_Detail_Record xmlns="">
      <PT_PARTICIPANT_FILE_IMP_ID>573794953</PT_PARTICIPANT_FILE_IMP_ID>
      <PT_LST_NM>GABRIEL</PT_LST_NM>
      <PT_FRST_NM>PETER</PT_FRST_NM>
      <EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
      <EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
      <EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
      <EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
    </Eligibility_Detail_Record>
  </EligibilityRecords>

ТРЕБОВАНИЯ

  1. Создайте новую Dependent_Record, которая является дочерней записью Eligibility_Detail_Record для каждого DP_PARTICIPANT_FILE_IMP_ID, который соответствует PT_PARTICIPANT_FILE_IMP_ID.
  2. Add an EN_PLAN_TYPE field for each Record that has an EN_PLAN_NAME of "Health Reimbursement Arrangement" that reads:
    • "Ind" if no dependents are found
    • "IndSpouse", если один и только один иждивенец имеет DP_RELATIONSHIP супруга
    • "IndChild", если один и только один зависимый имеет DP_RELATIONSHIP зависимого
    • «Семья», если более одного иждивенца

ОЖИДАЕМЫЙ РЕЗУЛЬТАТ

<EligibilityRecords xmlns="http://Eligibility_LSDD">
  <Eligibility_Detail_Record xmlns="">
    <PT_PARTICIPANT_FILE_IMP_ID>553739837</PT_PARTICIPANT_FILE_IMP_ID>
    <PT_LST_NM>DOE</PT_LST_NM>
    <PT_FRST_NM>JANE</PT_FRST_NM>
    <EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
    <EN_PLAN_TYPE>Family</EN_PLAN_TYPE>
    <EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
    <EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
    <EN_PLAN_YEAR_STRT_DT>01012017</EN_PLAN_YEAR_STRT_DT>
    <Dependent_Record>
      <DP_PARTICIPANT_FILE_IMP_ID>553739837</DP_PARTICIPANT_FILE_IMP_ID>
      <DP_DEPENDENT_FILE_IMP_ID>NC110012077673</DP_DEPENDENT_FILE_IMP_ID>
      <DP_RELATIONSHIP>Spouse</DP_RELATIONSHIP>
      <DP_LST_NM>DOE</DP_LST_NM>
      <DP_FRST_NM>JOHN</DP_FRST_NM>
    </Dependent_Record>
    <Dependent_Record>
      <DP_PARTICIPANT_FILE_IMP_ID>553739837</DP_PARTICIPANT_FILE_IMP_ID>
      <DP_DEPENDENT_FILE_IMP_ID>NC110012077680</DP_DEPENDENT_FILE_IMP_ID>
      <DP_RELATIONSHIP>Dependent</DP_RELATIONSHIP>
      <DP_LST_NM>DOE</DP_LST_NM>
      <DP_FRST_NM>JIMMY</DP_FRST_NM>
    </Dependent_Record>
  </Eligibility_Detail_Record>
  <Eligibility_Detail_Record xmlns="">
    <PT_PARTICIPANT_FILE_IMP_ID>610051908</PT_PARTICIPANT_FILE_IMP_ID>
    <PT_LST_NM>JACKSON</PT_LST_NM>
    <PT_FRST_NM>MICHAEL</PT_FRST_NM>
    <EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
    <EN_PLAN_TYPE>IndSpouse</EN_PLAN_TYPE>
    <EN_MBRSHP_EFF_STRT_DT>01012017</EN_MBRSHP_EFF_STRT_DT>
    <EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
    <EN_PLAN_YEAR_STRT_DT>01012017</EN_PLAN_YEAR_STRT_DT>
    <Dependent_Record>
      <DP_PARTICIPANT_FILE_IMP_ID>610051908</DP_PARTICIPANT_FILE_IMP_ID>
      <DP_DEPENDENT_FILE_IMP_ID>NC110015202761</DP_DEPENDENT_FILE_IMP_ID>
      <DP_RELATIONSHIP>Spouse</DP_RELATIONSHIP>
      <DP_LST_NM>JACKSON</DP_LST_NM>
      <DP_FRST_NM>MELISSA</DP_FRST_NM>
    </Dependent_Record>
  </Eligibility_Detail_Record>
  <Eligibility_Detail_Record xmlns="">
    <PT_PARTICIPANT_FILE_IMP_ID>561859010</PT_PARTICIPANT_FILE_IMP_ID>
    <PT_LST_NM>MCLEOD</PT_LST_NM>
    <PT_FRST_NM>CONOR</PT_FRST_NM>
    <EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
    <EN_PLAN_TYPE>IndChild</EN_PLAN_TYPE>
    <EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
    <EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
    <EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
    <Dependent_Record>
      <DP_PARTICIPANT_FILE_IMP_ID>561859010</DP_PARTICIPANT_FILE_IMP_ID>
      <DP_DEPENDENT_FILE_IMP_ID>SC000018241906</DP_DEPENDENT_FILE_IMP_ID>
      <DP_RELATIONSHIP>Dependent</DP_RELATIONSHIP>
      <DP_LST_NM>MCLEOD</DP_LST_NM>
      <DP_FRST_NM>DUNCAN</DP_FRST_NM>
    </Dependent_Record>
  </Eligibility_Detail_Record>
  <Eligibility_Detail_Record xmlns="">
    <PT_PARTICIPANT_FILE_IMP_ID>573794953</PT_PARTICIPANT_FILE_IMP_ID>
    <PT_LST_NM>GABRIEL</PT_LST_NM>
    <PT_FRST_NM>PETER</PT_FRST_NM>
    <EN_PLAN_NAME>Health Reimbursement Arrangement</EN_PLAN_NAME>
    <EN_MBRSHP_EFF_STRT_DT>01012016</EN_MBRSHP_EFF_STRT_DT>
    <EN_MBRSHP_EFF_END_DT></EN_MBRSHP_EFF_END_DT>
    <EN_PLAN_YEAR_STRT_DT>01012016</EN_PLAN_YEAR_STRT_DT>
    <EN_PLAN_TYPE>Ind</EN_PLAN_TYPE>
  </Eligibility_Detail_Record>
</EligibilityRecords>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes" omit-xml-declaration="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:key name="participants" match="Eligibility_Detail_Record" use="PT_PARTICIPANT_FILE_IMP_ID"/>

  <xsl:template match="/*">
    <xsl:copy>
      <xsl:for-each select="Eligibility_Detail_Record[string(PT_PARTICIPANT_FILE_IMP_ID)]
        [count(.|key('participants',PT_PARTICIPANT_FILE_IMP_ID)[1])=1]">
        <xsl:variable name="participantCount" select="count(key('participants',PT_PARTICIPANT_FILE_IMP_ID)[string(DP_PARTICIPANT_FILE_IMP_ID)])"/>
        <Eligibility_Detail_Record>
          <xsl:copy-of select="*[starts-with(name(),'PT_')]|EN_PLAN_NAME"/>
          <xsl:choose>
            <!--Add an EN_PLAN_TYPE field for each Record that has an EN_PLAN_NAME of "Health Reimbursement Arrangement" that reads:-->
            <xsl:when test="EN_PLAN_NAME='Health Reimbursement Arrangement'">
              <xsl:call-template name="HRA">
                <xsl:with-param name="participantCount" select="$participantCount"/>
              </xsl:call-template>
            </xsl:when>
          </xsl:choose>
          <xsl:copy-of select="*[not(self::EN_PLAN_NAME) and starts-with(name(),'EN_')]"/>
          <!--Create a new Dependent_Record that is a child record of Eligibility_Detail_Record for each DP_PARTICIPANT_FILE_IMP_ID that matches a PT_PARTICIPANT_FILE_IMP_ID-->
          <xsl:for-each select="key('participants',PT_PARTICIPANT_FILE_IMP_ID)[string(DP_PARTICIPANT_FILE_IMP_ID)]">
            <Dependent_Record>
              <xsl:copy-of select="*[starts-with(name(),'DP_')]"/>
            </Dependent_Record>
          </xsl:for-each>
        </Eligibility_Detail_Record>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>

  <xsl:template name="HRA">
    <xsl:param name="participantCount"/>
    <EN_PLAN_TYPE>
      <xsl:choose>
        <!--"Family" if more than one dependent-->
        <xsl:when test="$participantCount > 1">Family</xsl:when>
        <!--"IndChild" if one and only one dependent that has DP_RELATIONSHIP of Dependent-->
        <xsl:when test="$participantCount = 1 and DP_RELATIONSHIP = 'Dependent'">IndChild</xsl:when>
        <!--"IndSpouse" if one and only one dependent that has DP_RELATIONSHIP of Spouse-->
        <xsl:when test="$participantCount = 1 and DP_RELATIONSHIP = 'Spouse'">IndSpouse</xsl:when>
        <!--"Ind" if no dependents are found-->
        <xsl:when test="$participantCount = 0">Ind</xsl:when>
      </xsl:choose>
    </EN_PLAN_TYPE>
  </xsl:template>

</xsl:stylesheet>

Проблема в том, что DP_RELATIONSHIP проверяется на соответствие первому вхождению каждой ELIGIBILITY_DETAIL_RECORD для конкретного участника, которая всегда будет пустой. Я просто не уверен, как легко настроить его для проверки первого вхождения DP_RELATIONSHIP для записей, где существует зависимый (DP_DEPENDENT_FILE_IMP_ID найден) и participantCount< /strong> равно 1 (вероятно, мне следует переименовать переменную в dependCount, но я позабочусь об этом позже)


person Ritley572    schedule 07.02.2017    source источник
comment
Вместо ссылки на предыдущий вопрос, пожалуйста, полностью опишите здесь свою текущую проблему. Из вашего вопроса неясно, каковы ожидаемые и фактические результаты, и отсутствуют части вашего кода. Очень сложно понять, о чем вы спрашиваете, если нам сначала нужно прочитать и понять предыдущий вопрос и ответ на него.   -  person flyx    schedule 07.02.2017
comment
Я обновил вопрос, чтобы включить всю соответствующую информацию   -  person Ritley572    schedule 07.02.2017


Ответы (1)


Вместо того, чтобы собирать всех участников с ключом, я бы предложил просто собрать иждивенцев.

Верхний уровень шаблона записывает сначала элементы EN_PLAN_TYPE и Dependent_Record, используя ключ:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" omit-xml-declaration="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:key name="dependents" match="Eligibility_Detail_Record" use="DP_PARTICIPANT_FILE_IMP_ID"/>

    <xsl:template match="/*">
        <xsl:copy>
            <xsl:apply-templates select="Eligibility_Detail_Record[not(DP_PARTICIPANT_FILE_IMP_ID)]"/>
        </xsl:copy>
    </xsl:template>

    <!-- Template top level records -->
    <xsl:template match="Eligibility_Detail_Record[not(DP_PARTICIPANT_FILE_IMP_ID)]">
        <xsl:copy>
            <xsl:copy-of select="*[starts-with(name(),'PT_')]|EN_PLAN_NAME"/>
            <!--Add an EN_PLAN_TYPE field for each Record that has an EN_PLAN_NAME of "Health Reimbursement Arrangement" -->
            <xsl:if test="EN_PLAN_NAME='Health Reimbursement Arrangement'">
                <xsl:call-template name="HRA"/>
            </xsl:if>
            <xsl:copy-of select="*[not(self::EN_PLAN_NAME) and starts-with(name(),'EN_')]"/>
            <xsl:apply-templates select="key('dependents', PT_PARTICIPANT_FILE_IMP_ID)"/>
        </xsl:copy>
    </xsl:template>

    <!-- Template dependent records -->
    <xsl:template match="Eligibility_Detail_Record[DP_PARTICIPANT_FILE_IMP_ID]">
        <Dependent_Record>
            <xsl:copy-of select="*[starts-with(name(), 'DP_')]"/>
        </Dependent_Record>
    </xsl:template>

    <!-- Plan type -->
    <xsl:template name="HRA">
        <xsl:variable name="dependents" select="key('dependents', PT_PARTICIPANT_FILE_IMP_ID)"/>
        <xsl:variable name="participantCount" select="count($dependents)"/>
        <EN_PLAN_TYPE>
            <xsl:choose>
                <!--"Family" if more than one dependent-->
                <xsl:when test="$participantCount > 1">Family</xsl:when>
                <!--"IndChild" if one and only one dependent that has DP_RELATIONSHIP of Dependent-->
                <xsl:when test="$participantCount = 1 and $dependents/DP_RELATIONSHIP = 'Dependent'">IndChild</xsl:when>
                <!--"IndSpouse" if one and only one dependent that has DP_RELATIONSHIP of Spouse-->
                <xsl:when test="$participantCount = 1 and $dependents/DP_RELATIONSHIP = 'Spouse'">IndSpouse</xsl:when>
                <!--"Ind" if no dependents are found-->
                <xsl:when test="$participantCount = 0">Ind</xsl:when>
            </xsl:choose>
        </EN_PLAN_TYPE>
    </xsl:template>

</xsl:stylesheet>  
person teppic    schedule 07.02.2017
comment
Этот ответ кажется мне таким очевидным теперь, когда я его увидел. Если слишком долго смотреть на проблему, это может серьезно нарушить мыслительный процесс. Спасибо за помощь! - person Ritley572; 08.02.2017