XSLT слияние и сопоставление значений - PullRequest
2 голосов
/ 15 марта 2011

У меня есть проект, который, похоже, вышел из моей зоны комфорта и требует некоторой (продвинутой?) Обработки XSL.

У меня есть два следующих примера XML-документа:

doc1

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

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>

Мне нужно получить значение XModID из Doc2 и сопоставить его с соответствующим именем (значением) в Doc1. Однако есть еще одно осложнение, заключающееся в том, что это создает записи для загрузки в базу данных, поэтому в моем сценарии доктор Фибес находится в пределах <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 Ответ

1 голос
/ 15 марта 2011

Это преобразование:

<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')">
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...