XSLT:元素和计算的排名

时间:2013-03-25 18:09:24

标签: xml xslt

我为完全缺乏XML经验而道歉,但解决这个问题将有助于我理解如何使用XSLT进行计算。

我们有一个样本数据库,结构如下:

<HospitalML>
<Patients>
    <Patient>
        <Name>
            <FirstName>Salvatore</FirstName>
            <LastName>Piscuoglio</LastName>
        </Name>
        <Diagnoses>
            <Diagnosis>
                <Name>HCC</Name>
                <Weight>1.2</Weight>
            </Diagnosis>
            <Diagnosis>
                <Name>CRC</Name>
                <Weight>2.2</Weight>
            </Diagnosis>
        </Diagnoses>
    </Patient>
</Patients>
<Hospitals>
    <Hospital>
        <HospitalName>LondonGeneral</HospitalName>
        <Diagnoses>
            <Diagnosis>
                <Name>HCC</Name>
                <Weight>2.1</Weight>
            </Diagnosis>
            <Diagnosis>
                <Name>CRC</Name>
                <Weight>0.2</Weight>
            </Diagnosis>
        </Diagnoses>
    </Hospital>
    <Hospital>
        <HospitalName>EastEnd</HospitalName>
        <Diagnoses>
            <Diagnosis>
                <Name>HCC</Name>
                <Weight>1.7</Weight>
            </Diagnosis>
            <Diagnosis>
                <Name>CRC</Name>
                <Weight>0.7</Weight>
            </Diagnosis>
        </Diagnoses>
    </Hospital>
</Hospitals>

每位患者都有一组诊断,其“重量”值表明它们有多严重。 每个医院元素都有“诊断”子元素,表明他们管理的疾病和“体重”元素分数,表明他们在每个疾病中有多好。

我想从数据库中为患者Salvatore评估医院,并列出按分数排名的医院,表明他诊断的最佳分数。

对任何想法都会感激不尽。感谢。

1 个答案:

答案 0 :(得分:0)

这个xslt:

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

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <!-- You could select one specific patient instead of all if you prefer.-->
        <xsl:apply-templates select=".//Patient"/>
    </xsl:template>

    <!-- This template just copy a patient and his name and 'do the job' for all the diagnoses. -->
    <xsl:template match="Patient">
        <xsl:copy>
            <xsl:copy-of select="Name"/>
            <xsl:apply-templates select="Diagnoses/Diagnosis"/>
        </xsl:copy>
    </xsl:template>

    <!-- Here is the template for the patient diagnosis (the predicate is just there to prevent mistakes with diagnosis element child of hospital) -->
    <xsl:template match="Diagnosis[ancestor::Patient]">
        <!-- we store the name and weight inside variables to simplify the xpaths below.
            Actually you may use the current() function, but was'nt sure about its support in XSLT 1.0-->
        <xsl:variable name="name" select="Name"/>
        <xsl:variable name="patientWeight" select="Weight"/>
        <!-- first statement, copy the diagnosis and its name. -->
        <xsl:copy>        
            <xsl:copy-of select="Name"/>
            <!-- then, search for hospitals which got same diagnosis -->
            <xsl:apply-templates select="//Hospital[.//Diagnosis/Name = $name]">
                <!-- sort them by their weight in the current diagnosis. This is the "real job", where you got your hospital 'rank' for a diagnosis.  -->
                <xsl:sort select=".//Diagnosis[Name = $name]/Weight" order="descending"/>
                <!-- use this param to be able to output only the weight of the current diagnosis -->
                <xsl:with-param name="diagnosis" select="$name"/>
                <xsl:with-param name="patientWeight" select="$patientWeight"/> 
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>

    <!-- A simple template, that just output the hospital, its name and its weight score (aka : hospital weight * patient weight.  -->
    <xsl:template match="Hospital">
        <xsl:param name="diagnosis"/>
        <xsl:param name="patientWeight"/>
        <xsl:element name="Weight">                   
        <xsl:value-of select="number(.//Diagnosis[Name=$diagnosis]/Weight) * $patientWeight"/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

提供此xml输出:

<?xml version="1.0" encoding="utf-8"?>
<Patient>
   <Name>

      <FirstName>Salvatore</FirstName>

      <LastName>Piscuoglio</LastName>

   </Name>
   <Diagnosis>
      <Name>HCC</Name>
      <Hospital>
         <HospitalName>LondonGeneral</HospitalName>
         <Weight>2.52</Weight>
      </Hospital>
      <Hospital>
         <HospitalName>EastEnd</HospitalName>
         <Weight>2.04</Weight>
      </Hospital>
   </Diagnosis>
   <Diagnosis>
      <Name>CRC</Name>
      <Hospital>
         <HospitalName>EastEnd</HospitalName>
         <Weight>1.54</Weight>
      </Hospital>
      <Hospital>
         <HospitalName>LondonGeneral</HospitalName>
         <Weight>0.44</Weight>
      </Hospital>
   </Diagnosis>
</Patient>

您可以通过使用个人输出格式切换xsl:copy和xsl:copy-of调用来更改输出格式。

希望这会有所帮助。