0

<Database>2つの子要素を持つ要素を含む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各患者名が正確に1つの要素に含まれていると仮定すると、次のように機能するはずです。

<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 に答える