Получить уникальные значения с помощью XSLT 1.0 (без использования XSL: Key) - PullRequest
1 голос
/ 03 октября 2011

Я сталкиваюсь с типичной проблемой, пока получаю уникальный список с использованием XSLT 1.0.

Образец XSLT:

<xsl:if test="$tempVar = 'true'">
    <xsl:variable name="filePath" select="document($mPath)" />
    // Do something
    // I can't implement this using "Muenchian Method". 
    // Since, I can't declare <xsl:key> inside of <xsl:if>
    // There is no chance to declare <xsl:key> on top.
    // I should get unique list from here only
</xsl:if>

filepath переменная будет содержать XML следующим образом: -

<Root>
    <Data id="102">
        <SubData>
            <Info code="abc">Information 102</Info>
        </SubData>
    </Data>
    <Data id="78">
        <SubData>
            <Info code="def">Information 78</Info>
        </SubData>
    </Data>
    <Data id="34">
        <SubData>
            <Info code="abc">Information 34</Info>
        </SubData>
    </Data>
    <Data id="55">
        <SubData>
            <Info code="xyz">Information 55</Info>
        </SubData>
    </Data>
    <Data id="86">
        <SubData>
            <Info code="def">Information 86</Info>
        </SubData>
    </Data>
    <Data id="100">
        <SubData>
            <Info code="xyz">Information 100</Info>
        </SubData>
    </Data>
</Root>

Вывод: Уникальный список код должен быть

abc
def
xyz

Спасибо

Ответы [ 3 ]

2 голосов
/ 04 октября 2011
<xsl:if test="$tempVar = 'true'">
    <xsl:variable name="filePath" select="document($mPath)" />
    // Do something
    // I can't implement this using "Muenchian Method". 
    // Since, I can't declare <xsl:key> inside of <xsl:if>
    // There is no chance to declare <xsl:key> on top.
    // I should get unique list from here only
</xsl:if>

Это неправда, что нельзя использовать <xsl:key> и функцию key() в таких обстоятельствах :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kcodeByVal" match="@code" use="."/>

 <xsl:variable name="tempVar" select="'true'"/>

 <xsl:variable name="vrtfFilePath">
    <Root>
        <Data id="102">
            <SubData>
                <Info code="abc">Information 102</Info>
            </SubData>
        </Data>
        <Data id="78">
            <SubData>
                <Info code="def">Information 78</Info>
            </SubData>
        </Data>
        <Data id="34">
            <SubData>
                <Info code="abc">Information 34</Info>
            </SubData>
        </Data>
        <Data id="55">
            <SubData>
                <Info code="xyz">Information 55</Info>
            </SubData>
        </Data>
        <Data id="86">
            <SubData>
                <Info code="def">Information 86</Info>
            </SubData>
        </Data>
        <Data id="100">
            <SubData>
                <Info code="xyz">Information 100</Info>
            </SubData>
        </Data>
    </Root>
 </xsl:variable>

 <xsl:variable name="vfilePath"
      select="ext:node-set($vrtfFilePath)"/>

 <xsl:template match="/">
  <xsl:if test="$tempVar = 'true'">
     <xsl:for-each select="$vfilePath">
      <xsl:for-each select=
       "*/*/*/Info/@code
                    [generate-id()
                    =
                     generate-id(key('kcodeByVal',.)[1])
                     ]
       ">
       <xsl:value-of select="concat(.,' ')"/>
      </xsl:for-each>
     </xsl:for-each>
    </xsl:if>
 </xsl:template>

</xsl:stylesheet>

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

abc def xyz 
2 голосов
/ 03 октября 2011
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:template match="/">
        <xsl:apply-templates select="//Data[
                             not(
                                */Info/@code = preceding-sibling::Data/*/Info/@code
                             )
                         ]/*/Info/@code"/>
    </xsl:template>

    <xsl:template match="@*">
        <xsl:value-of select="."/>
        <xsl:text>&#xD;</xsl:text>
    </xsl:template>

</xsl:stylesheet>
1 голос
/ 03 октября 2011

Причина, по которой вы не используете мюнхенский метод или xsl: key, является ложной. Это будет работать на отлично. Возможно, вы не поняли, что когда вы объявляете определение ключа, оно не относится к конкретному исходному документу, оно позволяет вам использовать функцию key () для любого исходного документа.

...