使用 SSIS XML 源存储相对 xml 元素

Using a SSIS XML Source store relative xml elements

使用 SSIS XML 来源我想阅读以下内容 XML

<Stock>
  <OnHand>1</OnHand>
  <Proximity>xx</Proximity>
  <Reserved>2</Reserved>
  <Proximity>yy</Proximity>
  <OnOrder>3</OnOrder>
  <Proximity>zz</Proximity>
  <Cbo>4</Cbo>
  <Proximity>zz</Proximity>
</Stock>

无法更改XML,因为它是一个名为Onix的国际标准。

如您所见,每行后面都有一个 Proximity。

我想以某种方式以正确的顺序存储它们,或者在 OnHand 之后为 OnHandProximity 调用 Proximity。

此 XML 之后的架构如下所示:

<xs:sequence>
  <xs:element ref="OnHand" />
  <xs:element minOccurs="0" ref="Proximity" />
  <xs:sequence minOccurs="0">
    <xs:element ref="Reserved" />
    <xs:element minOccurs="0" ref="Proximity" />
  </xs:sequence>
  <xs:sequence minOccurs="0">
    <xs:element ref="OnOrder" />
    <xs:element minOccurs="0" ref="Proximity" />
  </xs:sequence>
  <xs:sequence minOccurs="0">
    <xs:element ref="CBO" />
    <xs:element minOccurs="0" ref="Proximity" />
  </xs:sequence>
</xs:sequence>

不幸的是,这在 SSIS 中正确给出了这个错误 XML 来源:

The XML Source was unable to process the XML data. Ambiguous complexType definition. The element "stock" has multiple members named "Proximity".

我的问题当然是,是否有人有建议在不丢失相对位置信息的情况下像这样处理 XML。

还有一个细节,行不是强制的,但我认为第一个解决方案可以忽略这个细节。

使用脚本组件作为源

XML 源不支持这些类型的 XML 文件,您应该添加脚本组件作为源,使用 C# 脚本反序列化 XML 文件使用 System.Xml 命名空间或类似程序集并生成输出行。您可以使用变量将 XML 文件路径传递给脚本。

有帮助links

类似问题

检查这个 link,它可能包含一些解决方法

使用脚本组件作为源

在 .Net 中处理 ONIX Xml

解决方法是在导入前转换 XML。 考虑执行以下操作。

由于我不是最擅长样式表转换的,请随时发表评论或提供更好的解决方案。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Stock/OnHand">
        <xsl:element name="./OnHand">
            <xsl:element name="OnHandValue">
                <xsl:value-of select="current()"/>
            </xsl:element>
            <xsl:element name="OnHandProximity">
                <xsl:choose>
                    <xsl:when test="following-sibling::*[1][self::Proximity]" >
                        <xsl:value-of select="following-sibling::*[1]" />
                    </xsl:when>
                </xsl:choose>
            </xsl:element>
        </xsl:element>
    </xsl:template> 
    <xsl:template match="Stock/Reserved">
        <xsl:element name="Reserved">
            <xsl:element name="ReservedValue">
                <xsl:value-of select="current()"/>
            </xsl:element>
            <xsl:element name="ReservedProximity">
                <xsl:choose>
                    <xsl:when test="following-sibling::*[1][self::Proximity]" >
                        <xsl:value-of select="following-sibling::*[1]" />
                    </xsl:when>
                </xsl:choose>
            </xsl:element>
        </xsl:element>
    </xsl:template> 
    <xsl:template match="Stock/OnOrder">
        <xsl:element name="OnOrder">
            <xsl:element name="OnOrderValue">
                <xsl:value-of select="current()"/>
            </xsl:element>
            <xsl:element name="OnOrderProximity">
                <xsl:choose>
                    <xsl:when test="following-sibling::*[1][self::Proximity]" >
                        <xsl:value-of select="following-sibling::*[1]" />
                    </xsl:when>
                </xsl:choose>
            </xsl:element>
        </xsl:element>
    </xsl:template> 
    <xsl:template match="Stock/CBO">
        <xsl:element name="CBO">
            <xsl:element name="CBOValue">
                <xsl:value-of select="current()"/>
            </xsl:element>
            <xsl:element name="CBOProximity">
                <xsl:choose>
                    <xsl:when test="following-sibling::*[1][self::Proximity]" >
                        <xsl:value-of select="following-sibling::*[1]" />
                    </xsl:when>
                </xsl:choose>
            </xsl:element>
        </xsl:element>
    </xsl:template> 

    <xsl:template match="Stock/Proximity" />
</xsl:stylesheet>