0

我有一个<Database>包含两个子元素的元素的 XML 文件<Patients> and <Hospitals>。每个<Patients>都有一个子元素<Patient>,其名称指定为属性。每个医院都有一个属性名,例如:<Hospital name="JR"和一个子元素<Patients>,它有子元素<Patient name="XY">

我想通过复制患者的结构来更新文件,然后添加医院信息。作为患者姓名的附加属性,或作为子元素。有什么想法吗?

编辑:谢谢蒂姆,这是示例。

<Database>
<Patients>
    <Patient name="Salvatore"/>
    <Patient name="Luca"/>
</Patients>
<Hospitals>
    <Hospital name="JR">
        <Patients>
            <Patient name="Salvatore"/>
        </Patients>
    </Hospital>
    <Hospital name="LondonGeneral">
        <Patients>
            <Patient name="Luca"/>
        </Patients>
    </Hospital>
</Hospitals>
</Database>

输出应如下所示:

    <?xml version="1.0" encoding="UTF-8"?>
<Database>
    <Patients>
        <Patient name="Salvatore" hospital="JR"/>
        <Patient name="Luca" hospital="LondonGeneral"/>
    </Patients>
    <Hospitals>
        <Hospital name="JR">
            <Patients>
                <Patient name="Salvatore"/>
            </Patients>
        </Hospital>
        <Hospital name="LondonGeneral">
            <Patients>
                <Patient name="Luca"/>
            </Patients>
        </Hospital>
    </Hospitals>
</Database>

感谢帮助。

4

1 回答 1

0

假设每个患者姓名都包含在一个Hospital元素中,以下应该有效

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

  <xsl:key name="hospitalPatientByName"
           match="Hospital/Patients/Patient"
           use="@name" />

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

  <xsl:template match="Patient[not(ancestor::Hospital)]">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:attribute name="hospital">
        <xsl:value-of select="key('hospitalPatientByName', @name)/ancestor::Hospital/@name" />
      </xsl:attribute>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

在这里,我们处理每个顶级元素,方法是根据患者姓名从Patient元素下查找对应的元素,然后提取包含医院的名称。PatientHospital

如果同一个名称Patient可能不止一个Hospital,那么我会使用子元素而不是属性

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

  <xsl:key name="hospitalPatientByName"
           match="Hospital/Patients/Patient"
           use="@name" />

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

  <xsl:template match="Patient[not(ancestor::Hospital)]">
    <xsl:copy>
      <xsl:apply-templates select="@*" />
      <xsl:apply-templates select="key('hospitalPatientByName', @name)/ancestor::Hospital" mode="in-patient" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Hospital" mode="in-patient">
    <xsl:copy><xsl:apply-templates select="@*" /></xsl:copy>
  </xsl:template>

</xsl:stylesheet>

鉴于您的样本输入,这将产生

<Database>
<Patients>
    <Patient name="Salvatore"><Hospital name="JR"/></Patient>
    <Patient name="Luca"><Hospital name="LondonGeneral"/></Patient>
</Patients>
<Hospitals>
    <Hospital name="JR">
        <Patients>
            <Patient name="Salvatore"/>
        </Patients>
    </Hospital>
    <Hospital name="LondonGeneral">
        <Patients>
            <Patient name="Luca"/>
        </Patients>
    </Hospital>
</Hospitals>
</Database>

如果(比如说)Luca 也在 JR 患者名单中,那么你会列出两家医院,即

<Patient name="Luca">
  <Hospital name="JR"/>
  <Hospital name="LondonGeneral"/>
</Patient>
于 2013-03-17T19:38:10.393 回答