如果在XPATH中不存在节点,如何返回常量?

时间:2012-09-03 14:06:38

标签: xml xpath ssis

我遇到了问题,请考虑以下XML:

<?xml version="1.0" encoding="UTF-16"?>
<APIDATA xmlns="api-com">
<ORDER EngineID="1" OrderID="66" OtherInfo="yes"><INSTSPECIFIER InstID="27" SeqID="17"/>     
</ORDER>
<ORDER EngineID="2" OrderID="67" OtherInfo="yes"><INSTSPECIFIER InstID="28" SeqID="18"/>    
</ORDER>
<ORDER EngineID="3" OrderID="68"><INSTSPECIFIER InstID="29" SeqID="19"/></ORDER>
</APIDATA>

我必须与SSIS合作。我想在所有Order条目的每个循环中获取所有数据到SSIS变量。到目前为止,我可以在SSIS中使用ForeachLoop控制流获取数据,具体如下:

EnumerationType:  ElementCollection
OuterXPathString: //*[name() = 'ORDER']
InnerElementType: NodeText
InnerXPathString: @*[name() = 'EngineID'] | @*[name() = 'OrderID'] | child::node()/@*[name() = 'InstID'] | child::node()/@*[name() = 'SeqID']

如何以这样的方式获取OtherInfo数据,即使节点不存在,它总是会返回一些东西?例如,如果节点不存在,则返回“否”。

在讨论方面,我需要这个,因为SSIS映射在结果集上使用整数索引。如果结果集可以是4或5长,我得到索引越界错误。这是我的想法,以避免问题,总是返回一个固定长度的结果集。

如果无法做到这一点,另一个想法是使用默认值扩展XML。所以如果另一个问题是:你能告诉我,如何使用XPATH向XML添加默认值?示例:为此提出上述XML:

<?xml version="1.0" encoding="UTF-16"?>
<APIDATA xmlns="api-com">
<ORDER EngineID="1" OrderID="66" OtherInfo="yes"><INSTSPECIFIER InstID="27" SeqID="17"/>     
</ORDER>
<ORDER EngineID="2" OrderID="67" OtherInfo="yes"><INSTSPECIFIER InstID="28" SeqID="18"/>    
</ORDER>
<ORDER EngineID="3" OrderID="68" OtherInfo="defaultvalue"><INSTSPECIFIER InstID="29" SeqID="19"/></ORDER>
</APIDATA>

或者在SSIS中有更优雅的解决方法吗?

1 个答案:

答案 0 :(得分:7)

  

如何以这种方式获取OtherInfo数据,它总是如此   回馈一些东西,即使节点不存在?例如,如果   节点不存在,返回“否”。

以下是生成OtherInfo属性值的一种方法,如果此属性存在或字符串"no"否则

      concat(@OtherInfo,
             substring('no',1 + 2*boolean(@OtherInfo)))

在以下元素上评估此Xpath 1.0表达式时:

    <ORDER EngineID="1" OrderID="66" OtherInfo="yes">
            <INSTSPECIFIER InstID="27" SeqID="17"/>

结果是:

yes

但是当评估相同的表达式时:

    <ORDER EngineID="3" OrderID="68">
            <INSTSPECIFIER InstID="29" SeqID="19"/>

然后结果是:

no

基于XSLT的验证

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/*/*">
         <xsl:value-of select=
         "concat(@OtherInfo,
                 substring('no',1 + 2*boolean(@OtherInfo)))
         "/>
 </xsl:template>
</xsl:stylesheet>

在提供的XML文档上应用此转换时:

<APIDATA xmlns="api-com">
        <ORDER EngineID="1" OrderID="66" OtherInfo="yes">
                <INSTSPECIFIER InstID="27" SeqID="17"/>
        </ORDER>
        <ORDER EngineID="2" OrderID="67" OtherInfo="yes">
                <INSTSPECIFIER InstID="28" SeqID="18"/>
        </ORDER>
        <ORDER EngineID="3" OrderID="68">
                <INSTSPECIFIER InstID="29" SeqID="19"/>
        </ORDER>
</APIDATA>

针对每个ORDER元素评估Xpath表达式,并将评估结果复制到输出

yesyesno

<强>解释

表达式:

      concat(@OtherInfo,
             substring('no',1 + 2*boolean(@OtherInfo)))

生成两个字符串的串联。

如果上下文节点具有名为OtherInfo的属性,则第二个字符串为空字符串,并且仅生成第一个字符串(属性的值)。

如果上下文节点没有名为OtherInfo 的属性,则concat()的第一个参数为空字符串,第二个参数将被计算并输出。

在这两种情况下,如何评估此子表达式:

substring('no',1 + 2*boolean(@OtherInfo))
  1. 如果@OtherInfo存在。然后2*boolean(@OtherInfo) = 2*true() = 2*1 = 2因此,表达式相当于:substring('no',3)这是空字符串,因为"no"的长度只有2。

  2. 如果@OtherInfo不存在。然后是2*boolean(@OtherInfo) = 2*false() = 2*0 = 0。因此,表达式等效于:substring('no',1),并且计算结果为"no"字符串。

相关问题