0

对于完全没有使用 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 的数据库中评估医院,并给出一个按分数排名的医院列表,表明他的诊断最好的医院。

将不胜感激任何想法。谢谢。

4

1 回答 1

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 调用切换为您的个人输出格式来更改输出格式。

希望这会有所帮助。

于 2013-03-25T23:20:20.873 回答