首页 > 解决方案 > 如何在 XSLT 中正确实现 if-else 条件?

问题描述

我有 XML,其中有一个 ContactRecords 节点:

<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>

我正在编写一个处理 ContactRecords 节点的 XSLT:

<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>
              ​​&lt;/xsl:for-each>
      ​&lt;/xsl:element>
   ​&lt;/xsl:for-each>
</xsl:element>

</xsl:template>

</xsl:transform>

我现在得到以下结果:

<h2>dooooooooooooo</h2>
<h2>dooooooooooooo</h2>
​​&lt;h2>dooooooooooooo</h2>

我希望收到:

<h2>mooooooooooooo</h2>
<h2>mooooooooooooo</h2>
​​&lt;h2>dooooooooooooo</h2>

我究竟做错了什么?

如果我用文字解释算法,那么我需要以下内容:如果 item 元素中有 Address 元素,则执行逻辑 1。如果 item 元素中没有 Address 元素,则执行逻辑 2。

如果我们用伪代码描述算法,那么这就是:

if (item.includes(Address)) {
 do logic #1
} else {
 do logic #2
}

UPD1:更新了 XML 和 XSLT 代码 UPD2:在标签地址中添加命名空间(可能原因在其中)

标签: xsltxpath

解决方案


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>

推荐阅读