条件不识别空元素时的XSL

时间:2017-10-02 11:09:49

标签: xml xslt

'当'条件不能正确识别空元素。所需的输出应显示' EMPTYAddress2'属性。我尝试了各种各样的' not'条件也没有运气。请帮助我成为新手。我正在使用Oxygen XML Developer,并且没有返回任何错误。

XML源文件:

<InterfaceData>
    <OBJECT_ACTION_ID>16283</OBJECT_ACTION_ID>
    <Employee>
        <Employee>
            <EmployeeBasic>
                <EmployeeNo>50064</EmployeeNo>
            </EmployeeBasic>
            <EmployeeBasic_DateMarriageCeased>
                <PersonDetailsRecords>
                    <PersonDetails>
                        <DateMarriageCeased/>
                    </PersonDetails>
                </PersonDetailsRecords>
            </EmployeeBasic_DateMarriageCeased>
            <EmployeeAddress>
                <AddressRecords>
                    <AddressDetails>
                        <Address1>Line1</Address1>
                        <Address2/>
                        <Address3>Line3</Address3>
                        <Address4>Line4</Address4>
                        <Postcode>Postcode</Postcode>
                    </AddressDetails>
                </AddressRecords>
            </EmployeeAddress>
        </Employee>
    </Employee>
</InterfaceData>

XSL样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:template match="/">
        <xsl:for-each-group select="//InterfaceData" group-by="OBJECT_ACTION_ID">
            <!-- Employee -->
            <EmployeeAddress>
                <xsl:for-each   select="current-group()//AddressDetails">
                    <xsl:call-template  name="CGIderiveAddress">
                        <xsl:with-param name="myVarAddress1" select="current-group()//Address1/text()"/>
                        <xsl:with-param name="myVarAddress2" select="current-group()//Address2/text()"/>
                        <xsl:with-param name="myVarAddress3" select="current-group()//Address3/text()"/>
                        <xsl:with-param name="myVarAddress4" select="current-group()//Address4/text()"/>
                        <xsl:with-param name="myVarPostcode" select="current-group()//Postcode/text()"/>
                    </xsl:call-template>
                </xsl:for-each>
            </EmployeeAddress>
        </xsl:for-each-group>
    </xsl:template>
    <xsl:template name="CGIderiveAddress">
        <xsl:param name="myVarAddress1"/>
        <xsl:param name="myVarAddress2"/>
        <xsl:param name="myVarAddress3"/>
        <xsl:param name="myVarAddress4"/>
        <xsl:param name="myVarPostcode"/>
        <xsl:attribute name="Address1">
            <xsl:value-of select="$myVarAddress1"/>
        </xsl:attribute>
        <xsl:choose>
            <!-- Address Line 2 is empty and Adress Line 3 exists -->
            <xsl:when test="$myVarAddress2 = ''">
                <xsl:attribute name="EMPTYAddress2">
                    <xsl:value-of select="'EMPTYAddress2'"/>
                </xsl:attribute>
            </xsl:when>
            <xsl:otherwise>
                <xsl:attribute name="NotEMPTYAddress2">
                    <xsl:value-of select="'NotEMPTYAddress2'"/>
                </xsl:attribute>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

XSL输出:

<?xml version="1.0" encoding="UTF-8"?>
<EmployeeAddress Address1="Line1"
                 NotEMPTYAddress2="NotEMPTYAddress2"/>

2 个答案:

答案 0 :(得分:1)

您正如此定义myVarAddress2 ...

<xsl:with-param name="myVarAddress2" select="current-group()//Address2/text()"/>

但输入XML示例中的Address2不包含任何子文本节点,因此$myVarAddress2参数包含空序列。空序列与空字符串不同,因此测试$myVarAddress2 = ''为假。

相反,当您使用XSLT 2.0时,您可以执行此操作....

<xsl:when test="empty($myVarAddress2)">

请注意,我无法看到分组如何进入您的XSLT,尤其是因为InterfaceData是根元素。

此外,对于问题中显示的XSLT,您可以简化参数,如此...

<xsl:with-param name="myVarAddress2" select="Address2/text()"/>

答案 1 :(得分:1)

使用/text()几乎总是一个错误。在这种情况下,如果Address2元素存在且没有子节点,则Address2 / text()是一个空序列(不是具有零长度字符串值的节点!);当你测试一个空序列是否与任何东西相等时,即使是一个零长度的字符串,结果总是为假。

我认为模板CGIderiveAddress期望它的所有参数都是字符串,因此最好使用as =&#34; xs:string&#34;来声明它。在xsl:param元素上。如果您已经这样做了,那么您将收到一条错误消息,指出您正在提供一个不允许的空序列。错误消息总是比不正确的结果更好,实现它们的一个好方法是声明所有变量和(特别是)参数的类型。

然后只需使用<xsl:with-param select="current-group()//Address2"/>。由于期望值是一个字符串,因此Address2元素将被雾化并变成一个字符串,如果Address2元素为空,它将是一个零长度字符串。如果在Address2不存在时您还需要零长度字符串,请使用string(current-group()//Address2)

更仔细地查看代码,这里还有另一个明显的错误:

<xsl:for-each select="current-group()//AddressDetails">
    <xsl:call-template  name="CGIderiveAddress">
      <xsl:with-param name="myVarAddress1" 
            select="current-group()//Address1/text()"/>

我确信您确实想要传递当前正在处理的AddressDetails的Address1值,而不是当前元素组的所有Address1值。那只是

<xsl:with-param name="myVarAddress1" select="Address1"/>