XSLT合并和匹配值

时间:2011-03-15 15:12:02

标签: xml database xslt

我有一个项目似乎已经从我的舒适区域移动了一些并且需要一些(高级?)XSL处理。

我有以下两个示例XML文档:

文档1

<instance>
    <InfBy1>Dr Phibes</InfBy1>
    <InfBy2>Dr X</InfBy2>
    <InfBy3>Dr Chivago</InfBy3>
</instance>

文档2

KB_XMod_Modules>
    <Physician>Dr Phibes</Physician>
    <XModID>60</XModID>
</KB_XMod_Modules>
<KB_XMod_Modules>
    <Physician>Dr X</Physician>
    <XModID>61</XModID>
</KB_XMod_Modules>
<KB_XMod_Modules>
    <Physician>Dr Chivago</Physician>
    <XModID>62</XModID>
</KB_XMod_Modules>

我必须从Doc2获取XModID值并将其与Doc1中的关联名称(值)匹配。然而,一个额外的复杂因素是创建记录以加载到数据库中,所以在我的场景中,Phibes博士在<InfBy1>范围内,但在另一条记录中,他可能会说<InfBy3>。无论如何,期望的输出将是:

<InfBy1>
    <items>
        <item>
            <label>Dr Phibes</label>
            <value>60</value>
        </item>
    </items>
</InfBy1>
<InfBy2>
    <items>
        <item>
            <label>Dr X</label>
            <value>61</value>
        </item>
    </items>
</InfBy2>
<InfBy3>
    <items>
        <item>
            <label>Dr Chivago</label>
            <value>62</value>
        </item>
    </items>
</InfBy3>

任何想法真的很感激......

谢谢,

威尔

1 个答案:

答案 0 :(得分:1)

此转化:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:key name="kPhysByName" match="KB_XMod_Modules"
          use="Physician"/>

 <my:doc2>
    <KB_XMod_Modules>
        <Physician>Dr Phibes</Physician>
        <XModID>60</XModID>
    </KB_XMod_Modules>
    <KB_XMod_Modules>
        <Physician>Dr X</Physician>
        <XModID>61</XModID>
    </KB_XMod_Modules>
    <KB_XMod_Modules>
        <Physician>Dr Chivago</Physician>
        <XModID>62</XModID>
    </KB_XMod_Modules>
 </my:doc2>

 <xsl:template match="/">
  <result>
   <xsl:apply-templates/>
  </result>
 </xsl:template>

 <xsl:template match="/*/*[starts-with(name(), 'InfBy')]">
  <xsl:variable name="vCur" select="."/>
  <xsl:for-each select="document('')">
   <xsl:variable name="vMod" select="key('kPhysByName', $vCur)"/>
   <xsl:copy>
    <items>
     <item>
      <label><xsl:value-of select="$vMod/Physician"/></label>
      <value><xsl:value-of select="$vMod/XModID"/></value>
     </item>
    </items>
   </xsl:copy>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

应用于第一个提供的XML文档(它包含第二个嵌入式 - 仅为方便起见):

<instance>
    <InfBy1>Dr Phibes</InfBy1>
    <InfBy2>Dr X</InfBy2>
    <InfBy3>Dr Chivago</InfBy3>
</instance>

会产生想要的正确结果:

<result xmlns:my="my:my">
    <items>
        <item>
            <label>Dr Phibes</label>
            <value>60</value>
        </item>
    </items>
    <items>
        <item>
            <label>Dr X</label>
            <value>61</value>
        </item>
    </items>
    <items>
        <item>
            <label>Dr Chivago</label>
            <value>62</value>
        </item>
    </items>
</result>

<强>解释

这种转变非常简单。为方便起见,我们使用键,出于同样的原因,我们将第二个文档嵌入到XSLT样式表中。 在实际应用中,第二个文档将是独立的,所需的唯一更改(除了从样式表中删除)将替换

  <xsl:for-each select="document('')">

使用:

  <xsl:for-each select="document('someURL')">