XSl - нужна помощь с трансформацией - PullRequest
2 голосов
/ 24 августа 2011

Я новичок в XSLT и пытаюсь решить следующее преобразование.

У меня есть XML, который выглядит следующим образом ...

<Groups>
 <Group>
  <GroupSelector>52</GroupSelector> 
  <GroupDescription>Group 52</GroupDescription> 
    <GroupValue>ABCD</GroupValue> 
 </Group>
 <Group>
  <GroupSelector>27</GroupSelector> 
  <GroupDescription>Group 27</GroupDescription> 
  <GroupValue>PQRS</GroupValue> 
 </Group>
 <Group>
  <GroupSelector>20</GroupSelector> 
  <GroupDescription>Group 20</GroupDescription> 
  <GroupValue>XYZA</GroupValue> 
 </Group>
 <Group>
  <GroupSelector>15</GroupSelector> 
  <GroupDescription>Group 15</GroupDescription> 
  <GroupValue>MNOP</GroupValue> 
 </Group>
</Groups>

Может быть от 0 до n чисел группы

.

Я пытаюсь применить XSLT, чтобы найти 'Group', где значение 'GroupSelector' равно 20, и создать вывод, подобный этому;

<GroupSelection ElementName="FoundGroup" Missing="false">20</GroupSelection>
<GroupSelection ElementName="GroupDes" Missing="false">Group 20</GroupSelection>
<GroupSelection ElementName="GroupVal" Missing="false">XYZA</GroupSelection>

Если ни у одной из n 'Group's нет' GroupSelector 'со значением 20, вывод должен быть таким;

<GroupSelection ElementName="FoundGroup" Missing="true"/>
<GroupSelection ElementName="GroupDes" Missing="true"/>
<GroupSelection ElementName="GroupVal" Missing="true"/>

Пожалуйста, помогите. Заранее спасибо.

Lola

Ответы [ 2 ]

3 голосов
/ 24 августа 2011

Если вам не нужно параметрическое преобразование, достаточно двух шаблонов с буквальными элементами результата (без AVT):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="text()"/>

    <xsl:template match="/*/Group[GroupSelector=20]">
        <GroupSelection ElementName="FoundGroup" Missing="false">
            <xsl:value-of select="GroupSelector"/>
        </GroupSelection>
        <GroupSelection ElementName="GroupDes" Missing="false">
            <xsl:value-of select="GroupDescription"/>
        </GroupSelection>
        <GroupSelection ElementName="GroupVal" Missing="false">
            <xsl:value-of select="GroupValue"/>
        </GroupSelection>
    </xsl:template>

    <xsl:template match="/*/Group[
        not(following::Group)
        and not(preceding::Group[GroupSelector=20])
        and not(GroupSelector=20)]">
        <GroupSelection ElementName="FoundGroup" Missing="true"/>
        <GroupSelection ElementName="GroupDes" Missing="true"/>
        <GroupSelection ElementName="GroupVal" Missing="true"/>
    </xsl:template>

</xsl:stylesheet>

В противном случае, если выбор группы является переменным (вам необходимо параметрическое преобразование), вы можетеДобавьте к этому решению полезный шаблон режима шаблона:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:param name="selector" select="20"/>

    <xsl:template match="/*/Group">
        <xsl:apply-templates select="self::*[GroupSelector=$selector]" 
            mode="selection"/>
        <xsl:apply-templates select="self::*[
            not(following::Group)
            and not(preceding::Group[GroupSelector=$selector])
            and not(GroupSelector=$selector)]" 
            mode="noselection"/>
    </xsl:template>

    <xsl:template match="Group" mode="selection">
        <GroupSelection ElementName="FoundGroup" Missing="false">
            <xsl:value-of select="GroupSelector"/>
        </GroupSelection>
        <GroupSelection ElementName="GroupDes" Missing="false">
            <xsl:value-of select="GroupDescription"/>
        </GroupSelection>
        <GroupSelection ElementName="GroupVal" Missing="false">
            <xsl:value-of select="GroupValue"/>
        </GroupSelection>
    </xsl:template>

    <xsl:template match="Group" mode="noselection">
        <GroupSelection ElementName="FoundGroup" Missing="true"/>
        <GroupSelection ElementName="GroupDes" Missing="true"/>
        <GroupSelection ElementName="GroupVal" Missing="true"/>
    </xsl:template>

</xsl:stylesheet>

Очевидно, что в XSLT 2.0 вы можете напрямую работать с переменной и писать что-то вроде:

<xsl:template match="/*/Group[GroupSelector=$selector]">

Таким образом, все становится проще.

1 голос
/ 24 августа 2011

Это простое (короткое, только один шаблон, без режимов, без осей) и мощное (параметризованное для работы с любым возможным идентификатором группы) преобразование :

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

 <xsl:param name="pGroupId" select="'20'"/>

 <xsl:variable name="vGroup" select=
     "/*/Group[GroupSelector=$pGroupId]"/>

 <xsl:template match="/">
     <GroupSelection ElementName="FoundGroup"
                     Missing="{not($vGroup)}">
        <xsl:apply-templates select="$vGroup/GroupSelector"/>
     </GroupSelection>
     <GroupSelection ElementName="GroupDes"
                Missing="{not($vGroup)}">
        <xsl:apply-templates select="$vGroup/GroupDescription"/>
     </GroupSelection>
     <GroupSelection ElementName="GroupVal"
                     Missing="{not($vGroup)}">
        <xsl:apply-templates select="$vGroup/GroupValue"/>
     </GroupSelection>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному документу XML :

<Groups>
 <Group>
  <GroupSelector>52</GroupSelector>
  <GroupDescription>Group 52</GroupDescription>
    <GroupValue>ABCD</GroupValue>
 </Group>
 <Group>
  <GroupSelector>27</GroupSelector>
  <GroupDescription>Group 27</GroupDescription>
  <GroupValue>PQRS</GroupValue>
 </Group>
 <Group>
  <GroupSelector>20</GroupSelector>
  <GroupDescription>Group 20</GroupDescription>
  <GroupValue>XYZA</GroupValue>
 </Group>
 <Group>
  <GroupSelector>15</GroupSelector>
  <GroupDescription>Group 15</GroupDescription>
  <GroupValue>MNOP</GroupValue>
 </Group>
</Groups>

дает требуемый, правильный результат :

<GroupSelection ElementName="FoundGroup" Missing="false">20</GroupSelection>
<GroupSelection ElementName="GroupDes" Missing="false">Group 20</GroupSelection>
<GroupSelection ElementName="GroupVal" Missing="false">XYZA</GroupSelection>

Если в вышеуказанном документемы изменили :

  <GroupSelector>20</GroupSelector>

на :

  <GroupSelector>21</GroupSelector>

и применили то же преобразование к измененному документу XML, снова к желаемому,получен правильный результат :

<GroupSelection ElementName="FoundGroup" Missing="true"/>
<GroupSelection ElementName="GroupDes" Missing="true"/>
<GroupSelection ElementName="GroupVal" Missing="true"/>

Пояснение : Использование:

  1. <xsl:variable>

  2. AVT (шаблоны значений атрибутов).

  3. Модель обработки XSLT и встроенный шаблон для текстаузлы .

...