2014-05-20 39 views
1

我一直在学习SQL Server(痛苦而缓慢),并最终得到了该死的东西来做我想做的事情,但有一个XML导入过程让我绊倒向上。我有一个复杂的XML文件,如采样(在此XML的详细信息可以在这里找到:http://wiki.eve-id.net/APIv2_Corp_AssetList_XML):在SSIS中将复杂XML转换为可用格式

<?xml version='1.0' encoding='UTF-8'?> 
<eveapi version="2"> 
    <currentTime>2010-12-19 07:15:16</currentTime> 
    <result> 
    <rowset name="assets" key="itemID" columns="itemID,locationID,typeID,quantity,flag,singleton"> 
     <row itemID="961254083" locationID="30001161" typeID="17177" quantity="1" flag="0" singleton="1" /> 
     <row itemID="961256074" locationID="30001161" typeID="27672" quantity="1" flag="0" singleton="1" /> 
     <row itemID="1270658107" locationID="30002583" typeID="17176" quantity="1" flag="0" singleton="1" /> 
     <row itemID="1000474513775" locationID="30002583" typeID="17407" quantity="1" flag="0" singleton="1"> 
     <rowset name="contents" key="itemID" columns="itemID,typeID,quantity,flag,singleton"> 
      <row itemID="1000515794105" typeID="255" quantity="1" flag="27" singleton="1" /> 
     </rowset> 
     </row> 
     <row itemID="1000474513607" locationID="30002583" typeID="17406" quantity="1" flag="0" singleton="1"> 
     <rowset name="contents" key="itemID" columns="itemID,typeID,quantity,flag,singleton"> 
      <row itemID="1000515772705" typeID="17686" quantity="1" flag="27" singleton="1" /> 
     </rowset> 
     </row> 
    </rowset> 
    </result> 
    <cachedUntil>2010-12-19 23:40:24</cachedUntil> 
</eveapi> 

因此,很自然SSIS snarks我,当我尝试导入此使用XML源代码的工具,因为它是'复杂'的XML(嘟gr)。理想情况下,我希望发生的事情是能够将这件事情变成SSIS数据流,以便将其转储到我的SQL数据库中的表中。时髦的东西来与额外的嵌套行,这些是嵌套在其他项目内的项目,我想保留嵌套信息。理想情况下,我想要做的是创建一个包含父项的itemID的新列,如果它位于顶层,则为0或null。这也需要重复父项的位置ID。因此,最终的输出将是一个包含以下行的表:itemID,locationID,typeID,quantity,flag,singleton,parentID。鉴于上面的例子中输入,输出应该是这个样子(假设.csv格式):

itemID, locationID, typeID, quantity, flag, singleton, parentID 
961254083, 30001161, 17177, 1, 0, 1, 0 
961256074, 30001161, 27672, 1, 0, 1, 0 
1270658107, 30002583, 17176, 1, 0, 1, 0 
1000474513775, 30002583, 17407, 1, 0, 1, 0 
1000515794105, 30002583, 255, 1, 27, 1, 1000474513775 
1000474513607, 30002583, 17406, 1, 0, 1, 0 
1000515772705, 30002583, 17686, 1, 27, 1, 1000474513607 

从我一直在使用Google(谷歌AAH的精彩功率)这是可能使用XSLT,但是在我刚刚了解到如何使用SSIS并在两周前以这种方式使用XML文件时,我对此类知识的了解并不多。我希望获得一些帮助,可以构建一个可以执行此转换的XSLT文件,或者其他可能更好的方法。

另外需要注意的一点是:无论是哪种解决方案,都不能涉及任何手动输入。我这样做是为了从人工输入系统中迁移出来,所以任何手动输入都会完全破坏这样做的目的。

非常感谢!

+0

XSLT是一个好主意。你可以发布你的预期产出的例子吗? – helderdarocha

+0

**如果**我正确理解了您的XML源文档,则需要将它导入两次,分成两个不同的表格 - 因此您需要两个XSLT样式表,每个导入一个。 –

+0

嗨Helderdarocha。因此,最终我需要它以表格格式输出,其中包含以下列:itemID,locationID,typeID,数量,标志,单身人士,parentID。所有这些都是原始XML,除了parentID,对于嵌套项目,它将为0或null,并为嵌套项目引用父项目。 –

回答

0

您的CSV风格输出实际上非常简单直接,可以通过XSLT获取。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text" encoding="utf-8" /> 

    <xsl:template match="/"> 
    <xsl:text>itemID, locationID, typeID, quantity, flag, singleton, parentID&#xA;</xsl:text> 
    <xsl:apply-templates select="//row" /> 
    </xsl:template> 

    <xsl:template match="row"> 
    <xsl:variable name="p" select="ancestor::row[1]" /> 
    <xsl:value-of select="concat(@itemID, ', ')" /> 
    <xsl:value-of select="concat(@locationID|$p/@locationID, ', ')" /> 
    <xsl:value-of select="concat(@typeID, ', ')" /> 
    <xsl:value-of select="concat(@quantity, ', ')" /> 
    <xsl:value-of select="concat(@flag, ', ')" /> 
    <xsl:value-of select="concat(@singleton, ', ')" /> 
    <xsl:value-of select="concat($p/@itemID, '&#xA;')" /> 
    </xsl:template> 
</xsl:stylesheet> 

产生

 
itemID, locationID, typeID, quantity, flag, singleton, parentID 
961254083, 30001161, 17177, 1, 0, 1, 
961256074, 30001161, 27672, 1, 0, 1, 
1270658107, 30002583, 17176, 1, 0, 1, 
1000474513775, 30002583, 17407, 1, 0, 1, 
1000515794105, 30002583, 255, 1, 27, 1, 1000474513775 
1000474513607, 30002583, 17406, 1, 0, 1, 
1000515772705, 30002583, 17686, 1, 27, 1, 1000474513607 

的一件事没什么看头的XSLT程序是此行

<xsl:value-of select="concat(@locationID|$p/@locationID, ', ')" /> 

这里@locationID|$p/@locationID选择工会当前<row>@locationID和的容器<row>。这个XPath最多可以返回两个属性节点,但这里的基本假设是它们是互斥的。

这是一个小窍门,使线路在两种情况下工作,同时避免条件。但是,如果我的基本假设是错误的,表达式的结果也是错误的。

如果您在理解解决方案时遇到困难,请阅读<xsl:apply-templates>的工作原理。

+0

Woot!完美的作品,感谢Tomalak! –

+0

但你有没有理解解决方案,这是个问题? – Tomalak

+2

它的片断,是的。在处理文件时,我意识到在完整的xml中存在多个嵌套层次(这是以上样本的几倍)。对你的xslt做了一些调整,使它可以追赶到4层嵌套。我认为它不会比这更深,但如果是这样,我会进一步调整它。此外,由于只有顶层嵌套才具有locationID,并且嵌套项目永远不会位于与其父对象不同的位置,因此union函数可以很好地工作。我随时了解( - : –