Опустить пустые элементы из вывода XSLT 1.0 - PullRequest
0 голосов
/ 07 июня 2018

Я использую XSLT 1.0 для преобразования документа XML в другую схему XML.Исходный документ может иметь или не иметь элементы в зависимости от исходной базы данных, из которой он построен.

EG

   <Patients>
        <Patient id="1019">
            <Surname>Acqua</Surname>
            <Forenames>Matthew James</Forenames>
            <VoicePhone>0111 222 33333</VoicePhone>
        </Patient>
        <Patient id="1020">
            <Surname>Red</Surname>
            <Forenames>James Alan</Forenames>
        </Patient>
    </Patients>

Полученный результат после преобразования через XML будет содержать пустые элементы, потому чтоVoicePhone во втором пациенте не существует (а не существует, но он пуст).

XSLT имеет следующий вид:

<xsl:template match="//Patients/Patient">
<PatientRxs>
  <PatientInfo>
    <FirstName>
      <xsl:value-of select="Forenames"/>
    </FirstName>
    <Telephone>
      <xsl:value-of select="VoicePhone"/>
    </Telephone>
  </PatientInfo>
</PatientRxs>
</xsl:template>

И в итоге я получаю:

<PatientRxs>
    <PatientInfo>
        <FirstName>Matthew James</FirstName>
        <Telephone>0111 222 33333</Telephone>
    </PatientInfo>
</PatientRxs>
<PatientRxs>
    <PatientInfo>
        <FirstName>James Alan</FirstName>
        <Telephone/>
    </PatientInfo>
</PatientRxs>

Где я на самом деле хочу:

<PatientRxs>
    <PatientInfo>
        <FirstName>Matthew James</FirstName>
        <Telephone>0111 222 33333</Telephone>
    </PatientInfo>
</PatientRxs>
<PatientRxs>
    <PatientInfo>
        <FirstName>James Alan</FirstName>
    </PatientInfo>
</PatientRxs>

Хотя я мог бы проверить, существует ли значение, это всего лишь 1 из сотен элементов, которые потенциально могут не существовать в исходном документе и хотели бы избежатьлист XSLT, проверяющий каждый из них

Ответы [ 3 ]

0 голосов
/ 08 июня 2018
<xsl:template match="Patients">
        <xsl:element name="PatientRxs">
            <xsl:for-each select="Patient">
                <xsl:element name="PatientInfo">
                    <xsl:element name="Forenames">
                        <xsl:value-of select="Forenames"/>
                    </xsl:element>
                    <xsl:if test="VoicePhone">
                        <xsl:element name="Telephone">
                            <xsl:value-of select="VoicePhone"/>
                        </xsl:element>
                    </xsl:if>
                </xsl:element>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>
Test if Voicephone exist then insert element otherwise not.
0 голосов
/ 09 июня 2018
<xsl:template match="Patients">
        <xsl:element name="PatientRxs">
            <xsl:for-each select="Patient">
                <xsl:element name="PatientInfo">
                    <xsl:element name="Forenames">
                        <xsl:value-of select="Forenames"/>
                    </xsl:element>
                    <xsl:apply-templates select="VoicePhone"/>
                        </xsl:element>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>
    <xsl:template match="VoicePhone">
        <xsl:choose>
            <xsl:when test="text()">
                <xsl:element name="Telephone">
                    <xsl:value-of select="."/>
                </xsl:element>
            </xsl:when>
            <xsl:when test="empty(.)"/>
        </xsl:choose>
      </xsl:template>

Попробуйте это

0 голосов
/ 07 июня 2018

Попробуйте использовать общий шаблон, который соответствует любому элементу, но принимает параметр, позволяющий переименовать этот элемент

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:output method="xml" indent="yes" />
  <xsl:strip-space elements="*" />

  <xsl:template match="//Patients/Patient">
    <PatientRxs>
      <PatientInfo>
        <xsl:apply-templates select="Forenames" mode="field">
          <xsl:with-param name="newName" select="'FirstName'" />
        </xsl:apply-templates>
        <xsl:apply-templates select="VoicePhone" mode="field">
          <xsl:with-param name="newName" select="'Telephone'" />
        </xsl:apply-templates>
      </PatientInfo>
    </PatientRxs>
  </xsl:template>

  <xsl:template match="*" mode="field">
      <xsl:param name="newName" select="local-name()" />

      <xsl:element name="{$newName}">
          <xsl:value-of select="." />
      </xsl:element>
  </xsl:template>

</xsl:stylesheet>

Таким образом, если сопоставляемый элемент не существует, для этого элемента ничего не выводитсяна все.

...