Stackoverflow新手,并向XML询问有关XML的问题。我是一名具有SPSS背景的数据管理员,所以XML并不总是我的强项。我正在尝试将从分层数据库导出并以XML格式存储的数据集转换为CSV格式,原因有很多。原始数据库的结构不是很好,这导致了我的XSLT问题。
这是我必须使用的XML。这是一个700mb的文件:
<ABC_Data>
<UID>1</UID>
<DocumentNumber>000000001</DocumentNumber>
<Surname>Smith</Surname>
<GivenName>John</GivenName>
<BirthDateList>
<BirthDate>19/06/19888</BirthDate>
</BirthDateList>
<StationNumberList>
<StationNumber>2009981</StationNumber>
</StationNumberList>
<Reference>
<ReferenceEn>RG 150, Volume 01 - 1</ReferenceEn>
<ReferenceFr>RG 150, Volume 01 - 1</ReferenceFr>
</Reference>
<DigitizeList>
<Image>http://data.foo.bar.com/733a.gif</Image>
<Image>http://data2.for.bar.com/733b.gif</Image>
</DigitizeList>
<UID>2</UID>
<DocumentNumber>000000002</DocumentNumber>
<Surname>Kootz</Surname>
<GivenName>Ernst</GivenName>
<BirthDateList>
<BirthDate>24/12/1984</BirthDate>
</BirthDateList>
<StationNumberList>
<StationNumber>2000023</StationNumber>
</StationNumberList>
<Reference>
<ReferenceEn>RG 150, Volume 01 - 1</ReferenceEn>
<ReferenceFr>RG 150, Volume 01 - 1</ReferenceFr>
</Reference>
<DigitizeList>
<Image>http://data.foo.bar.com/744a.gif</Image>
<Image>http://data2.for.bar.com/755b.gif</Image>
</DigitizeList>
</ABC_Data>
以下是基本 XSLT我正在使用(from this thread)将其转换为CSV格式。发生的事情是记录没有正确嵌套,因此我无法获得将文件中的一条记录区分开来的输出。此外,多个<Image>
字段在输出上被收集在一起而没有插入分隔符,即它们将1个字段转换为2个或3个或4个不同的字段,因为<Image>
的数量可能在文本[编辑:现在解决]。
这是XSLT:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="iso-8859-1"/>
<xsl:strip-space elements="*" />
<xsl:template match="/*/child::*">
<xsl:for-each select="child::*">
<xsl:if test="position() != last()"><xsl:value-of select="normalize-space(.)"/>;</xsl:if>
<xsl:if test="position() = last()"><xsl:value-of select="normalize-space(.)"/>;</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
1;0000000001;Smith;John;19/06/19888;2009981;RG 150, Volume 01 - 1;RG 150, Volume 01 - 1;>http://data.foo.bar.com/733a.gif;http://data2.for.bar.com/733b.gif
2;0000000002;Koontz;Ernst;24/12/1984;2000023;RG 150, Volume 01 - 1;RG 150, Volume 01 - 1;http://data.foo.bar.com/744a.gif;http://data2.for.bar.com/755b.gif
有人能提出前进的方向吗?我想清理它以便
我的XSLT知识已有近10年的历史,所以我可以利用社区的支持来获得帮助。
感谢。
答案 0 :(得分:1)
试试这个
DECLARE @Shift TABLE (ShiftID INT, [Day] VARCHAR(3), DoctorId INT, FromTime TIME, ToTime TIME)
INSERT INTO @Shift
VALUES (1,'SUN',1,'08:00:00','16:00:00'),
(2,'MON',1,'09:00:00.00','14:00:00'),
(3,'TUE',1,'09:00:00.00','15:00:00'),
(4,'WED',1,'10:00:00.00','17:00:00'),
(5,'THU',1,'13:00:00.00','18:00:00')
DECLARE @D1 DATE, @D2 DATE
SET @D1 = '2017-02-19'
SET @D2 = '2017-02-28'
;WITH Calendar AS
(
SELECT @D1 AS [DateVal], LEFT(DATENAME(WEEKDAY,@D1),3) AS [DWName]
UNION ALL
SELECT DATEADD(DAY,1,DateVal), LEFT(DATENAME(WEEKDAY,DATEADD(DAY,1,DateVal)),3)
FROM Calendar
WHERE DateVal<@D2
)
SELECT S.DoctorId, C.DateVal, S.[Day], S.FromTime, S.ToTime
FROM @Shift S
JOIN Calendar C ON S.[Day]=C.DWName
答案 1 :(得分:0)
AFAICT,以下样式表将产生与预期输出几乎相同的结果:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*" />
<xsl:key name="cells" match="ABC_Data/*[not(self::UID)]" use="generate-id(preceding-sibling::UID[1])" />
<xsl:template match="/ABC_Data">
<xsl:for-each select="UID">
<xsl:apply-templates select=". | key('cells', generate-id())"/>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
<xsl:template match="*[not(*)]">
<xsl:value-of select="." />
<xsl:text>;</xsl:text>
</xsl:template>
</xsl:stylesheet>
唯一的区别是每行保留一个尾随的;
字符。这是因为我们不知道哪个元素是其行中的最后一个单元格 - 以及它是否包含多个子元素。
如果你知道这一点,你可以添加一个名称匹配的模板。否则,您必须先将每行放入变量中,然后输出变量而不使用其最后一个字符:
<xsl:template match="/ABC_Data">
<xsl:for-each select="UID">
<xsl:variable name="row">
<xsl:apply-templates select=". | key('cells', generate-id())"/>
</xsl:variable>
<xsl:value-of select="substring($row, 1, string-length($row) - 1)" />
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
顺便说一句,我怀疑这个结果是否有用。作为CSV文件的收件人,我希望每列都有来自同一域的数据(事实上,我希望每列都有一个标签)。至少在理论上,您的输入可能包含具有不同数量的BirthDates,StationNumbers,References等的记录,从而导致行包含未对齐列中的不同数量的单元格。