如何在 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 条件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在python的类中正确实现辅助函数

在这种情况下,如何在 Flutter 中正确实现 FutureBuilder?

如何在php中正确实现结构化菜单

ios - 如何在 ios swift 中正确实现后台获取

如何在 Keras 中正确实现自定义活动正则化器?

如何在 Windows 10 UWP 中正确实现语音识别