xpath получает совпадения в подсписке - PullRequest
1 голос
/ 31 мая 2011

У меня есть следующий xml:

    <vo class="GroupEntry" buildByAlias="true">
        <objectClass name="groupOfNames"/>
        <field name="commonName"          nameLDAP="cn"          type="String"/>
        <field name="descriptione"         nameLDAP="description"          type="String"/>
        <field name="member"              nameLDAP="member"               type="String[]"/>
    </vo>
    <update method="addMember" modificationMode="ADD_ATTRIBUTE">
        <input>
            <field name="member"/>        
            <field name="description"/>        
        </input>
    </update>

Я использую XSLT для его преобразования, и мне нужно для каждого обновления получать поля в vo, которые соответствуютполе, определенное во входных данных.Было бы что-то вроде этого:

<xsl:variable name="fields" select="vo/field" />
<xsl:for-each select="update">
    <xsl:variable name='fieldsForInput' select = "$fields[@name]=input/fields[@name]"/>
    <xsl:for-each select="$fieldsForInput">
       <xsl:value-of select="@type"/> <xsl:value-of select="@name"/>
    <xsl:for-each>
</xsl:for-each>

Но ничего не нашлось.Есть идеи?

Спасибо

JL

Ответы [ 2 ]

1 голос
/ 31 мая 2011

Из приведенных фрагментов трудно помочь вам и понять, чего вы хотите.Однако ваш случай кажется идеальным для использования xsl:key.

Например, если вы создаете ключ в начале преобразования следующим образом:

<xsl:key name="fields" match="vo/field" use="@name"/>

Вы можете использовать его внутри соответствияшаблон выглядит следующим образом:

        <xsl:for-each select="update/input">
            <xsl:copy-of select="key('fields',current()/field/@name)"/>
        </xsl:for-each>

Я бы не стал использовать xsl:foreach в любом случае.Но трудно дать вам полное решение, если вы предоставите только фрагменты.Также неясно, хотите ли вы просто сопоставить или заменить field.


Пример, показывающий, как получить поле name/type для каждого update/input/field.

XSLT1.0 проверено с Saxon 6.5.5

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

 <xsl:key name="fields" match="vo/field" use="@name"/>

 <xsl:template match="/root">
     <xsl:apply-templates select="update"/>
 </xsl:template>

 <xsl:template match="update">
     <xsl:value-of select="concat('-',@method,'&#xA;')"/>
     <xsl:apply-templates select="input/field"/>
 </xsl:template>

 <xsl:template match="input/field">
    <xsl:value-of select="concat('--',@name,' ',key('fields',@name)/@type,'&#xA;')"/>
 </xsl:template>

</xsl:stylesheet>

Применено:

<root>
    <vo class="GroupEntry" buildByAlias="true">
        <objectClass name="groupOfNames"/>
        <field name="commonName"          nameLDAP="cn"          type="String"/>
        <field name="description"         nameLDAP="description"          type="String"/>
        <field name="member"              nameLDAP="member"               type="String[]"/>
    </vo>
    <update method="addMember" modificationMode="ADD_ATTRIBUTE">
        <input>
            <field name="member"/>        
            <field name="description"/>        
        </input>
    </update>
        <update method="deleteMember" modificationMode="DELETE_ATTRIBUTE">
        <input>
            <field name="member"/>        
            <field name="description"/>        
        </input>
    </update>
</root>

Производит:

-addMember
--member String[]
--description String
-deleteMember
--member String[]
--description String
0 голосов
/ 31 мая 2011

Два решения:

Solution1 (без ключей):

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

 <xsl:template match=
  "vo/field[@name=../../update/*/*/@name]">

  <xsl:value-of select="concat(@name,' ',@type,'&#xA;')"/>
 </xsl:template>
</xsl:stylesheet>

При применении к предоставленному документу XML (исправлено, чтобы сделать его правильно оформленным):

<t>
    <vo class="GroupEntry" buildByAlias="true">
        <objectClass name="groupOfNames"/>
        <field name="commonName" nameLDAP="cn" type="String"/>
        <field name="description" nameLDAP="description" type="String"/>
        <field name="member" nameLDAP="member" type="String[]"/>
    </vo>
    <update method="addMember" modificationMode="ADD_ATTRIBUTE">
        <input>
            <field name="member"/>
            <field name="description"/>
        </input>
    </update>
</t>

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

description String
member String[]

Решение2 (с помощью ключа):

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

 <xsl:key name="kFieldByName" match="vo/field"
  use="@name"/>

 <xsl:template match="/*">
  <xsl:apply-templates mode="selected" select=
    "key('kFieldByName', update/*/*/@name)"/>
 </xsl:template>

 <xsl:template match="vo/field" mode="selected">
  <xsl:value-of select="concat(@name,' ',@type,'&#xA;')"/>
 </xsl:template>
</xsl:stylesheet>

при применении к тому же XML-документу (см. Выше), получается тот же правильный результат :

description String
member String[]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...