Xml 在XSLT中使用If-Else
如果条件匹配,我需要选择一个节点。我对XSLT一无所知,试图寻找答案,但找不到适合我的解决方案。 当有AddressType=Personal时,我想选择一个地址,如果没有AddressType=Personal,请检查“Second”,如果没有,请检查“Office”。 一个正常的If-Else。 我尝试了和,如果XML文件中只存在一种类型的AddressType,这可能会起作用。在我的例子中,XML文件中最多可以有11个地址类型(随机顺序),我只能传递一个 这看起来像我的源XML:Xml 在XSLT中使用If-Else,xml,xslt,Xml,Xslt,如果条件匹配,我需要选择一个节点。我对XSLT一无所知,试图寻找答案,但找不到适合我的解决方案。 当有AddressType=Personal时,我想选择一个地址,如果没有AddressType=Personal,请检查“Second”,如果没有,请检查“Office”。 一个正常的If-Else。 我尝试了和,如果XML文件中只存在一种类型的AddressType,这可能会起作用。在我的例子中,XML文件中最多可以有11个地址类型(随机顺序),我只能传递一个 这看起来像我的源XML: <
<Person>
<address>
<street></street
<number></number>
<City></City>
<AddressType>Personal</AddressType>
</address>
<address>
<street></street
<number></number>
<City></City>
<AddressType>Second</AddressType>
</address>
<address>
<street></street
<number></number>
<City></City>
<AddressType>Office</AddressType>
</address>
</Person>
您可以使用xsl:choose:
<xsl:choose>
<xsl:when test"some condition">
Statement...
</xsl:when>
<xsl:when test="some other condition">
Statement...
</xsl:when>
<xsl:otherwise>
Default...
</xsl:otherwise>
</xsl:choose>
陈述
陈述
违约
您需要使用
另一个选项是使用模板匹配来获得所需的案例,而不是在xsl:choose中嵌套所有内容。以这个XSLT为例
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="Person[address/AddressType='Personal']" priority="3">
Match Personal
</xsl:template>
<xsl:template match="Person[address/AddressType='Second']" priority="2">
Match Second
</xsl:template>
<xsl:template match="Person[address/AddressType='Office']" priority="1">
Match Office
</xsl:template>
<xsl:template match="Person">
Match None
</xsl:template>
</xsl:stylesheet>
匹配个人
比赛第二名
赛会办公室
不匹配
请注意,具有更特定模式的模板优先于没有模式的模板(这就是为什么除非任何其他模板不匹配,否则不会调用最后一个“Person”模板。对于其他模板,如果所有三个模板都匹配,则优先级属性越高。因此“Personal”即使存在其他属性,也将始终选择
(如果没有一个模板具有priority属性,那么在这种情况下将选择最后一个匹配的属性)。在XSLT 1.0中,有一种简单的方法可以做到这一点:
<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:param name="pAddressTypes" select="'PersonalSecondOffice'"/>
<xsl:template match="/*">
<xsl:apply-templates select="address">
<xsl:sort select=
"string-length(substring-before($pAddressTypes, AddressType))"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="address">
<xsl:if test="position() = 1">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
有点不清楚您的规则是什么。您是否只想筛选地址
中包含个人
或秒
或办公室
,还是需要根据地址类型
自定义输出?用户1292411:您可能有兴趣找到一个更简短的sol比当前接受的解决方案更简单。根本不需要使用xsl:choose
。接受的解决方案的大小将随着选项的数量成比例增长。有一种更简单、更短的解决方案,它的大小是固定的,而与选项的数量无关。:)我尝试了这个方法,似乎有效。因此,第一个“when”比下一个等具有优先级……这是否正确?根本不需要使用xsl:choose
。此解决方案将随着选项数量的增加而成比例增长。有一种更简单、更短的解决方案,它的大小是固定的,与options.thx的数量无关。我试图在biztalk项目中实现这一点,但不断出现错误,可能是由于biztalk中实际架构的复杂性。我在when中使用了choose,但稍后将尝试此解决方案。我是否遗漏了某些内容,或者pAddressTypes参数是否应设置为“Office,Second,Personal”之类的内容,即增加优先级顺序,以便按字符串长度排序获得最高优先级的地址?很好的技巧-我想到了某种地图,但你的方法更简单。@Kevan:排序是递增的——这意味着在“PersonalSecondOffice”
“PersonalSecondOffice”
中,“Personal”将排在第一位——因此它具有最高的优先级。Duh我没有发现办公室里的单引号
<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:param name="pAddressTypes" select="'PersonalSecondOffice'"/>
<xsl:template match="/*">
<xsl:apply-templates select="address">
<xsl:sort select=
"string-length(substring-before($pAddressTypes, AddressType))"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="address">
<xsl:if test="position() = 1">
<xsl:copy-of select="."/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
<Person>
<address>
<street></street>
<number></number>
<City></City>
<AddressType>Office</AddressType>
</address>
<address>
<street></street>
<number></number>
<City></City>
<AddressType>Personal</AddressType>
</address>
<address>
<street></street>
<number></number>
<City></City>
<AddressType>Second</AddressType>
</address>
</Person>
<address>
<street/>
<number/>
<City/>
<AddressType>Personal</AddressType>
</address>