如何在 XSLT 中正确实现 if-else 条件?
Posted
技术标签:
【中文标题】如何在 XSLT 中正确实现 if-else 条件?【英文标题】:How to correctly implement the if-else condition in XSLT? 【发布时间】:2021-09-19 15:43:21 【问题描述】:我有一个包含 ContactRecords 节点的 XML:
<Organisations>
<Organisation>
<Tag1>ValueElementTag1</Tag1>
<Tag2>ValueElementTag2</Tag2>
<Tag3>ValueElementTag3</Tag3>
<ContactRecords>
<item>
<ContactRecordType>AAAAA</ContactRecordType>
<ContactValue>ValueAAAAA</ContactValue>
<Address xmlns="http://www.v8.1c.ru/ssl/contactinfo" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AdrTag1 xsi:type="Adr">Example1</AdrTag1>
<AdrTag2>Example2</AdrTag2>
</Address>
</item>
<item>
<ContactRecordType>BBBBB</ContactRecordType>
<ContactValue>ValueBBBBB</ContactValue>
<Address xmlns="http://www.v8.1c.ru/ssl/contactinfo" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AdrTag1 xsi:type="Adr">Example1</AdrTag1>
<AdrTag2>Example2</AdrTag2>
</Address>
</item>
<item>
<ContactRecordType>CCCCC</ContactRecordType>
<ContactValue>ValueCCCCC</ContactValue>
</item>
</ContactRecords>
</Organisation>
<Organisation>
<Tag1>ValueElementTag1</Tag1>
<Tag2>ValueElementTag2</Tag2>
<Tag3>ValueElementTag3</Tag3>
<ContactRecords>
<item>
<ContactRecordType>AAAAA</ContactRecordType>
<ContactValue>ValueAAAAA</ContactValue>
<Address xmlns="http://www.v8.1c.ru/ssl/contactinfo" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AdrTag1 xsi:type="Adr">Example1</AdrTag1>
<AdrTag2>Example2</AdrTag2>
</Address>
</item>
<item>
<ContactRecordType>BBBBB</ContactRecordType>
<ContactValue>ValueBBBBB</ContactValue>
<Address xmlns="http://www.v8.1c.ru/ssl/contactinfo" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AdrTag1 xsi:type="Adr">Example1</AdrTag1>
<AdrTag2>Example2</AdrTag2>
</Address>
</item>
<item>
<ContactRecordType>CCCCC</ContactRecordType>
<ContactValue>ValueCCCCC</ContactValue>
</item>
</ContactRecords>
</Organisation>
</Organisations>
我正在编写一个 XSLT,它可以处理 ContactRecords 节点:
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:element name="Organisations">
<xsl:for-each select="Organisations/Organisation">
<xsl:element name="name(.)">
<xsl:for-each select="*[not(name()='ContactRecords')]">
<xsl:copy select="*">
<xsl:value-of select="normalize-space(.)"/>
</xsl:copy>
</xsl:for-each>
<xsl:for-each select="ContactRecords/item">
<xsl:choose>
<xsl:when test="Address">
<h2>mooooooooooooo</h2>
</xsl:when>
<xsl:otherwise>
<h2>dooooooooooooo</h2>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:transform>
我现在得到以下结果:
<h2>dooooooooooooo</h2>
<h2>dooooooooooooo</h2>
<h2>dooooooooooooo</h2>
我希望收到:
<h2>mooooooooooooo</h2>
<h2>mooooooooooooo</h2>
<h2>dooooooooooooo</h2>
我做错了什么?
如果我用文字解释算法,那么我需要以下内容:如果item元素中有Address元素,那么我们做逻辑1。如果item元素中没有Address元素,那么我们做逻辑2号。
如果我们用伪代码描述算法,那么是这样的:
if (item.includes(Address))
do logic #1
else
do logic #2
UPD1:更新了 XML 和 XSLT 代码 UPD2:在标签地址中添加命名空间(可能原因在其中)
【问题讨论】:
您的输入样本甚至不是格式正确的,因此我们不知道最小但完整的样本看起来如何,但在xsltfiddle.liberty-development.net/jxWZS7p,您的带有更正输入样本的代码看起来不错。 @MartinHonnen,我已经完成了现在看起来的 XML 和 XSLT 代码 @MartinHonnen,在标签地址中添加命名空间(可能原因在其中) 是的,如果元素在命名空间中,那么测试Address
不会测试它,因为它会测试 no 命名空间中名为 Address
的元素。所以在你的样式表中声明例如xmlns:ci="http://www.v8.1c.ru/ssl/contactinfo"
并在支票中使用 ci:Address
。
【参考方案1】:
Address
元素位于命名空间中,因此您的测试:
<xsl:when test="Address">
每次都返回false
。试试这种方式(最小化当前问题):
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://www.v8.1c.ru/ssl/contactinfo"
exclude-result-prefixes="ns0">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/Organisations">
<Organisations>
<xsl:for-each select="Organisation">
<xsl:copy>
<!-- omitted -->
<xsl:for-each select="ContactRecords/item">
<h2>
<xsl:choose>
<xsl:when test="ns0:Address">mooooooooooooo</xsl:when>
<xsl:otherwise>dooooooooooooo</xsl:otherwise>
</xsl:choose>
</h2>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</Organisations>
</xsl:template>
</xsl:stylesheet>
【讨论】:
以上是关于如何在 XSLT 中正确实现 if-else 条件?的主要内容,如果未能解决你的问题,请参考以下文章