3

我有一个问题,请考虑以下 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 合作。我想在所有订单条目的每个循环中获取所有数据到 SSIS 变量。到目前为止,我可以在 SSIS 的控制流中使用 ForeachLoop 获取数据,其中包括:

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

我怎样才能以这种方式获取 OtherInfo 数据,即使节点不存在,它也总是会返回一些东西?例如,如果节点不存在,则返回“No”。

在讨论方面,我需要这个,因为 SSIS 映射在结果集上使用整数索引。如果结果集可以是 4 或 5 长,我会得到 index out of bounds 错误。这是我规避问题的想法,始终返回固定长度的结果集。

如果无法做到这一点,另一个想法是使用默认值扩展 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 中有没有更优雅的方法来解决这个问题?

4

1 回答 1

7

我怎样才能以这种方式获取 OtherInfo 数据,即使节点不存在,它也总是会返回一些东西?例如,如果节点不存在,则返回“No”。

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>

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

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)而this是空字符串,因为"no"长度只有2。

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

于 2012-09-03T17:02:11.643 回答