我有一项任务要求我提取一组xml文件,这些文件都是相关的,然后从这些文件中挑出一部分记录,转换一些列,然后使用不同的格式导出到单个xml文件
我是SSIS的新手,到目前为止,我已经成功地导入了两个xml文件(为简单起见,仅从两个文件开始)。
第一个文件我们称之为“项目”,包含一些基本元数据,其中包括ID,用于识别第二个文件“里程碑”中的相关记录。我在数据流中使用查找转换过滤我的“有效记录” - 现在我有了有效的项ID来获取我需要的记录。我将这些有效的ID(以及Item.xml中的其余列通过Sort,然后进入合并连接)汇总。
第二个文件由2个输出构成,一个包含两列(ItemID和RowID)。第二个包含所有里程碑相关数据和一个RowID。我把这些通过内部合并连接,基于RowID,所以我将ItemID与里程碑数据一起使用。然后我使用ItemID在两个文件上进行完全外连接合并连接。
这给了我这样的数据:
我可以通过派生列转换来放置这些数据来创建我实际需要的数据列,但是我无法看到如何以关系方式构造它/将其规范化为不同的xml格式。
想法是输出类似的东西:
<item id="1">
<Milestone id="2">
<Milestone />
<Milestone id="3">
<Milestone />
</item>
有人能指出我正确的方向吗?
更新 更详细的描述我所拥有的,以及我想要实现的目标:
Item.xml:
<Items>
<Item ItemID="1">
<Title>
Data
</Title>
</Item>
<Item ItemID="2">
...
</Item>
...
</Items>
Milestone.xml:
<Milestones>
<Item ItemID="2">
<MS id="3">
<MS_DATA>
Data
</MS_DATA>
</MS>
<MS id="4">
<MS_DATA>
Data
</MS_DATA>
</MS>
</Item>
<Item ItemID="3">
<MS id="5">
<MS_DATA>
Data
</MS_DATA>
</MS>
</item>
</Milestones>
当我使用XML源时,它在SSIS中呈现的方式并不完全直观,这意味着Item行和MS行是两个单独的输出。我必须通过连接运行它们才能获得与特定项目对应的里程碑。这里没问题,然后通过与项目的完全外连接运行它,所以我得到一个包含多行的扁平表,其中包含明显相同的项目数据和MS的不同数据。基本上我得到了我试图在我的表中显示的内容,每个独特的MilestoneData都有大量冗余的Item数据。
最后它必须看起来类似于:
<NewItems>
<myNewItem ItemID="2">
<SomeDataDirectlyFromItem>
e.g. Title
</SomeDataDirectlyFromItem>
<DataConstructedFromMultipleColumnsInItem>
<MyMilestones>
<MS_DATA_TRANSFORMED MSID="3">
data
</MS_DATA_TRANSFORMED>
<MS_DATA_TRANSFORMED MSID="4">
data
</MS_DATA_TRANSFORMED>
</MyMilestones>
</DataConstructedFromMultipleColumnsInItem>
<myNewItem ItemID="3">
<SomeDataDirectlyFromItem>
e.g. Title
</SomeDataDirectlyFromItem>
<DataConstructedFromMultipleColumnsInItem>
<MyMilestones>
<MS_DATA_TRANSFORMED MSID="5">
data
</MS_DATA_TRANSFORMED>
</MyMilestones>
</DataConstructedFromMultipleColumnsInItem>
</myNewItem>
<myNewItem ItemID="4">
<SomeDataDirectlyFromItem>
e.g. Title
</SomeDataDirectlyFromItem>
<DataConstructedFromMultipleColumnsInItem>
<MyMilestones></MyMilestones>
</DataConstructedFromMultipleColumnsInItem>
</myNewItem>
</NewItems>
答案 0 :(得分:0)
我会尝试使用组件类型为script component
的{{1}}来处理此问题。因为你是ssis的新手,我假设你之前没有使用过它。所以基本上你
transformation
input_xml
您将面临最后可能会使用两行的问题,例如
ItemID[1] - MilestoneData[2];...
将导致
ItemID[1] - MilestoneData[2]
我使用Pentaho kettle做了类似的事情,即使没有使用<item id="1">
<Milestone id="2">
之类的东西来定义自己的逻辑。但我想ssis在这里缺乏任务。
答案 1 :(得分:0)
如何将XML导入关系表(例如在tempdb中),然后使用FOR XML PATH重构XML? FOR XML PATH可以高度控制XML的外观。下面是一个非常简单的例子:
CREATE TABLE #items ( itemId INT PRIMARY KEY, title VARCHAR(50) NULL )
CREATE TABLE #milestones ( itemId INT, msId INT, msData VARCHAR(50) NOT NULL, PRIMARY KEY ( itemId, msId ) )
GO
DECLARE @itemsXML XML
SELECT @itemsXML = x.y
FROM OPENROWSET( BULK 'c:\temp\items.xml', SINGLE_CLOB ) x(y)
INSERT INTO #items ( itemId, title )
SELECT
i.c.value('@ItemID', 'INT' ),
i.c.value('(Title/text())[1]', 'VARCHAR(50)' )
FROM @itemsXML.nodes('Items/Item') i(c)
GO
DECLARE @milestoneXML XML
SELECT @milestoneXML = x.y
FROM OPENROWSET( BULK 'c:\temp\milestone.xml', SINGLE_CLOB ) x(y)
INSERT INTO #milestones ( itemId, msId, msData )
SELECT
i.c.value('@ItemID', 'INT' ),
i.c.value('(MS/@id)[1]', 'VARCHAR(50)' ) msId,
i.c.value('(MS/MS_DATA/text())[1]', 'VARCHAR(50)' ) msData
FROM @milestoneXML.nodes('Milestones/Item') i(c)
GO
SELECT
i.itemId AS "@ItemID"
FROM #items i
INNER JOIN #milestones ms ON i.itemId = ms.itemId
FOR XML PATH('myNewItem'), ROOT('NewItems'), TYPE
DROP TABLE #items
DROP TABLE #milestones