我正在使用xslt 1.0将XML转换为PDF。我必须选择覆盖给定条件“IsBeneficialOwner = false”的所有唯一memberId。
<xsl:for-each select="//clientMembers/memberId" >
<xsl:if test="not(contains(/clientMemberRelations[IsBeneficialOwner='true']/memberId))" >
<fo:table-row>
<fo:table-cell xsl:use-attribute-sets="white">
<fo:block white-space-treatment="preserve"
><xsl:value-of select="//clientMembers/memberId"
/><fo:leader/></fo:block>
</fo:table-cell>
<fo:table-cell xsl:use-attribute-sets="white">
<fo:block white-space-treatment="preserve"
><xsl:value-of select="//clientMembers/name/name"
/><fo:leader/></fo:block>
</fo:table-cell>
<fo:table-cell xsl:use-attribute-sets="white">
<fo:block white-space-treatment="preserve"
><xsl:value-of select="//clientMembers/type/memberType"
/><fo:leader/></fo:block>
</fo:table-cell>
<fo:table-cell xsl:use-attribute-sets="white">
<fo:block white-space-treatment="preserve"
><xsl:value-of select="//clientMemberRelations/association/associationToEntity"
/><fo:leader/></fo:block>
</fo:table-cell>
</fo:table-row>
</xsl:if>
</xsl:for-each>
上面有什么问题不包含条件?我在控制台中收到以下错误 -
javax.xml.transform.TransformerException:FuncContains只允许2个参数
示例XML文件位于 -
之下 <clientMemberRelations>
<updateSource>xxxxx</updateSource>
<ownedEntityMemberId>2</ownedEntityMemberId>
<association>
<associationToEntity>Controlling Person </associationToEntity>
</association>
<IsBeneficialOwner>true</IsBeneficialOwner>
<memberId>6</memberId>
</clientMemberRelations>
<clientMemberRelations>
<updateSource>xxxxx</updateSource>
<ownedEntityMemberId>2</ownedEntityMemberId>
<association>
<associationToEntity>Controlling Person </associationToEntity>
</association>
<IsBeneficialOwner>false</IsBeneficialOwner>
<memberId>4</memberId>
</clientMemberRelations>
<clientMembers>
<address>
<proofSourceDmcId>0</proofSourceDmcId>
<postalZipCode>0-0</postalZipCode>
<updateSource>xxx</updateSource>
<city>xxx</city>
<proofSourceDmcVersion>0</proofSourceDmcVersion>
<stateProvince>xxx</stateProvince>
<Country>xxxxx</Country>
<type>xx</type>
<line1>xxxx</line1>
<ISOCountry>xxx</ISOCountry>
</address>
<memberId>4</memberId>
</clientMembers>
如您所见,XML有2个节点clientMemberRelations和clientMembers。 我必须选择clientMembers Nodes中的所有memberId,但是我必须省略那些“IsBeneficialOwner”标志为“true”的memberId。 我尝试了几种xsl:for-each和xsl:variable的组合,但没有得到所需的结果。
请建议是否可以使用XSLT 1.0以及如何实现?
答案 0 :(得分:0)
您关注的表达方式是
not(contains(/clientMemberRelations[IsBeneficialOwner='true']/memberId))
如果将其分成多行,可能更容易看到问题(这在语法上是正确的XPath,尽管人们可能不会通过查看Web上的示例来了解它。)
not(
contains(
/clientMemberRelations[IsBeneficialOwner='true']/memberId
)
)
你现在看到问题了吗? not
函数应该接受一个参数,并在此处获取一个参数。 contains
函数需要两个参数(这是您的错误消息所说的内容,但是FuncContains&#39;可能不是最明显的方式来引用contains()
函数XPath),但你只给它一个。
从您提供的片段中,如果有问题的成员ID包含某些魔术子字符串,或者如果成员ID包含在包含所有成员列表的某个字符串中,您似乎希望发出表格行要在表中生成行的ID。在第一种情况下,您需要类似
的内容not(contains(
/clientMemberRelations[IsBeneficialOwner='true']/memberId,
$magic-string
)
)
在第二种情况下,你想要像
这样的东西not(contains(
$wanted-list,
/clientMemberRelations[IsBeneficialOwner='true']/memberId
)
)
这就是你问的问题的答案。
另一方面,你对这个问题的散文描述暗示了一些完全不同的东西,这需要一个不同的解决方案。这两个分析的唯一共同点是,您似乎需要更好地理解contains()
函数的作用(并且您应该知道您想要问什么问题并提出问题)
你说
我必须选择覆盖给定条件的所有唯一memberId&#34; IsBeneficialOwner = false&#34;
我认为您的意思是,对于for-each循环中的每个memberId
元素,您要检查该成员ID是否显示为集合/clientMemberRelations [IsBeneficialOwner='true'] /memberId
中元素的值。最简单的方法是将for-each循环表示为:
<xsl:for-each select="//clientMembers/memberId" >
<xsl:choose>
<xsl:when test=". = /clientMemberRelations
[IsBeneficialOwner='true']
/memberId">
<!--* it's a beneficial owner, no output here! *-->
</xsl:when>
<xsl:when test=". = /clientMemberRelations
[IsBeneficialOwner='false']
/memberId">
<!--* it's not a beneficial owner, write a row! *-->
<fo:table-row>
...
</
</
<xsl:when test=". = /clientMemberRelations
[IsBeneficialOwner]
/memberId>
... handle the case where there is an `IsBeneficialOwner`
element but it's neither true nor false ...
</
<xsl:when test=". = /clientMemberRelations
[not(IsBeneficialOwner)]
/memberId>
... handle the case where there is no `IsBeneficialOwner`
element as sibling of the memberId ...
and also the case where there is no such element ...
</
<xsl:otherwise>
... handle any remaining cases ...
</
</
</
答案 1 :(得分:0)
除了Michael Sperberg-McQueen的评论之外,我只会注意到
<xsl:for-each select="//clientMembers/memberId" >
<xsl:if test="not(contains(/clientMemberRelations[IsBeneficialOwner='true']/memberId))" >
看起来不对,因为测试表达式对xsl:for-each
选择的每个节点都具有相同的值。我认为你几乎肯定希望test
属性中的表达式根据上下文项目给出不同的结果,而且这个表达式不会。