我有一个XSLT模板,我需要有条件地合并两个节点列表。我有以下两个XML片段:
<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>
我想创建一个与输入/字段具有相同节点的xml片段。对于这些节点中的每一个,我想检查列表vo / field中是否存在具有相同名称的节点。如果有,则应将其复制到新列表中。否则,它应该复制我们正在迭代的同一节点。在这种情况下,输出应该是这样的:
<field name="userPassword" nameLDAP="userPassword" type="String" hidden="true"/>
<field name="oldPasswordInQuotes" nameLDAP="unicodePwd" type="String"/>
到目前为止,我进行了以下转型:
<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:消息似乎表明副本工作正常,但是当我尝试迭代它时,它显然不起作用(只有一条消息&#34;参数找到&#34;它不是显示参数名称)。我错过了什么?
答案 0 :(得分:1)
我想你想要的东西:
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),尝试:
<xsl:for-each select="$allParameters/field">
<!-- your code here -->
</xsl:for-each>