通过从另一个列表复制来创建节点列表 [英] Create list of nodes by copying from another lists

查看:188
本文介绍了通过从另一个列表复制来创建节点列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个XSLT模板,我需要有条件地合并两个节点列表。我有以下两个XML片段:

I have a XSLT template where I need to merge two lists of nodes conditionally. I have the following two XML fragments:

<vo>
    <field name="userLoginName"       nameLDAP="uid"              type="String"/>
    <field name="displayName"         nameLDAP="displayName"      type="String"/>
    <field name="firstName"           nameLDAP="givenName"        type="String"/>
    <field name="lastName"            nameLDAP="sn"               type="String"/>
    <field name="mail"                nameLDAP="mail"             type="String"/>
    <field name="userPassword"        nameLDAP="userPassword"     type="String" hidden="true"/>
    <field name="center"              nameLDAP="center"           type="String"/>
</vo>

<input>
    <field name="userPassword"/>
    <field name="oldPasswordInQuotes" nameLDAP="unicodePwd"       type="byte[]"/>        
</input>

我想创建一个与input / field具有相同nodeas的xml片段。对于这些节点中的每一个,我想检查在列表vo /字段中是否存在具有相同名称的节点。如果有,则应将其复制到新列表。否则,它应该复制我们正在迭代的同一个节点。在这种情况下,输出应该是这样:

I want to create a xml fragment that will have the same nodeas as input/field. For each one of those nodes I want to check if there is a node with the same name in the list vo/field. If there is, then it should be copied to the new list. Otherwise, it should copy the same node we are iterating over. In this case the output should be something like this:

<field name="userPassword"        nameLDAP="userPassword"     type="String" hidden="true"/>
<field name="oldPasswordInQuotes" nameLDAP="unicodePwd"       type="String"/>        

到目前为止,我进行了以下转换:

So far I've the following transformation:

    <xsl:variable name="fields" select="vo/field" />

    <xsl:variable name='allParameters'>
        <xsl:for-each select="input/field">
            <xsl:variable name="inputFieldName" select="@name"/>
            <xsl:choose>
                <xsl:when test="$fields[@name = $inputFieldName]">
                    <xsl:copy-of select="$fields[@name = $inputFieldName]"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:copy-of select="."/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
    </xsl:variable>

    <xsl:message>Parameters <xsl:copy-of select="$allParameters" /> </xsl:message>

    <xsl:for-each select="$allParameters">
        <xsl:message>Parameter <xsl:value-of select="@name" /> found !!! </xsl:message>
    </xsl:for-each>

输出为

Parameters <field name="userPassword" nameLDAP="userPassword" type="String" hidden="true"/><field name="oldPasswordInQuotes" nameLDAP="unicodePwd" type="byte[]"/>
Parameter  found !!!

第一个xsl:消息似乎表明副本工作正常,但是当我尝试迭代它,它显然不工作(只有一个消息参数找到,它没有显示参数名称)。

The first xsl:message seems to show that the copy worked fine, but when I try to iterate over it, it is obviously not working(there is only one message "Parameter found" and it is not showing the parameter name). What am I missing?

推荐答案

我想要:

XSLT 1.0

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

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

<xsl:template match="/">
    <xsl:for-each select="root/input/field">
        <xsl:choose>
            <xsl:when test="key('vo', @name)">
                <xsl:copy-of select="key('vo', @name)"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:copy-of select="."/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:for-each>
</xsl:template>

</xsl:stylesheet>

应用于受欢迎的输入

<root>
    <vo>
        <field name="userLoginName"       nameLDAP="uid"              type="String"/>
        <field name="displayName"         nameLDAP="displayName"      type="String"/>
        <field name="firstName"           nameLDAP="givenName"        type="String"/>
        <field name="lastName"            nameLDAP="sn"               type="String"/>
        <field name="mail"                nameLDAP="mail"             type="String"/>
        <field name="userPassword"        nameLDAP="userPassword"     type="String" hidden="true"/>
        <field name="center"              nameLDAP="center"           type="String"/>
    </vo>
    <input>
        <field name="userPassword"/>
        <field name="oldPasswordInQuotes" nameLDAP="unicodePwd"       type="byte[]"/>        
    </input>
</root>

会导致:

<field name="userPassword" nameLDAP="userPassword" type="String" hidden="true"/>
<field name="oldPasswordInQuotes" nameLDAP="unicodePwd" type="byte[]"/>






编辑:



要回答你关于测试中消息数量的问题:只有一个 $ allParameters 节点; (假设XSLT 2.0),尝试:


To answer your question regarding the number of messages in your test: there is only one $allParameters node; to iterate over its inner nodes (assuming XSLT 2.0), try:

<xsl:for-each select="$allParameters/field">
    <!-- your code here -->
</xsl:for-each>

这篇关于通过从另一个列表复制来创建节点列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆