XSLT将具有重复子结构的xml转换为平面文件
我有一个如下所示的xml:XSLT将具有重复子结构的xml转换为平面文件,xslt,xslt-2.0,xslt-1.0,xslcompiledtransform,Xslt,Xslt 2.0,Xslt 1.0,Xslcompiledtransform,我有一个如下所示的xml: <?xml version="1.0" encoding="utf-8"?> <GetSavedReportResponse> <ResponseType>Success</ResponseType> <FileModifiedDateTime>2012-01-03T17:05:04</FileModifiedDateTime> <FileSizeBytes>7816&
<?xml version="1.0" encoding="utf-8"?>
<GetSavedReportResponse>
<ResponseType>Success</ResponseType>
<FileModifiedDateTime>2012-01-03T17:05:04</FileModifiedDateTime>
<FileSizeBytes>7816</FileSizeBytes>
<FileDataFormat>XML</FileDataFormat>
<FileData>
<Zthes>
<term>
<termId>49555</termId>
<termUpdate>add</termUpdate>
<termName>Active Personnel</termName>
<termVocabulary>People Status Global</termVocabulary>
<termVocabulary>Global People Status</termVocabulary>
<termCategory>PDA</termCategory>
<termCategory>PDI</termCategory>
<termCategory>GLB</termCategory>
<relation weight="100">
<termId>49556</termId>
<relationType>EQ</relationType>
<termName>term name</termName>
<termVocabulary>term vocabulary</termVocabulary>
</relation>
<relation weight="100">
<termId>49557</termId>
<relationType>BT</relationType>
<termName>General Active Personnel</termName>
<termVocabulary>People Status Global Updated</termVocabulary>
</relation>
</term>
<term>
<termId>49556</termId>
<termUpdate>add</termUpdate>
<termName>Leave of Absence Personnel</termName>
<termVocabulary>People Status Global</termVocabulary>
<termCategory>GLB</termCategory>
<termCategory>PDI</termCategory>
<relation weight="100">
<relationType>BT</relationType>
<termId>49554</termId>
<termName>General Non-Active Personnel</termName>
<termVocabulary>People Status Global</termVocabulary>
</relation>
</term>
</Zthes>
</FileData>
</GetSavedReportResponse>
成功
2012-01-03T17:05:04
7816
XML
49555
添加
现役人员
全球人口状况
全球人民地位
掌上电脑
PDI
GLB
49556
情商
术语名称
术语词汇
49557
英国电信
一般现役人员
人员状态全球更新
49556
添加
休假人员
全球人口状况
GLB
PDI
英国电信
49554
一般非现役人员
全球人口状况
我需要把它转换成平面文件。为此,我编写了以下xsl
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" />
<xsl:template match="Zthes">
<xsl:text> </xsl:text>
<xsl:for-each select="term">
<xsl:text>"</xsl:text>
<xsl:text>GL</xsl:text>
<xsl:text>"</xsl:text>
<xsl:text>;</xsl:text>
<xsl:text>"</xsl:text>
<xsl:for-each select="termCategory">
<xsl:value-of select="." />
</xsl:for-each>
<xsl:text>"</xsl:text>
<xsl:text>;</xsl:text>
<xsl:text>"</xsl:text>
<xsl:for-each select="termVocabulary">
<xsl:value-of select="." />
</xsl:for-each>
<xsl:text>"</xsl:text>
<xsl:text>;</xsl:text>
<xsl:text>"</xsl:text>
<xsl:for-each select="relation/termVocabulary">
<xsl:value-of select="." />
</xsl:for-each>
<xsl:text>"</xsl:text>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
"
德国劳埃德船级社
"
;
"
"
;
"
"
;
"
"
因此,输出应该是
“人类发展报告”;“文本”;"20120112045620";“F”
“德国劳埃德船级社”;“PDA”;“全球人民地位”;“术语词汇表”
“德国劳埃德船级社”;“PDA”;“全球人民地位”;“人员状态全局更新”
“德国劳埃德船级社”;“PDA”;“全球人民地位”;“术语词汇表”
“德国劳埃德船级社”;“PDA”;“全球人民地位”;“人员状态全局更新”
“德国劳埃德船级社”;“PDI”;“全球人民地位”;“术语词汇表”
“德国劳埃德船级社”;“PDI”;“全球人民地位”;“人员状态全局更新”
“德国劳埃德船级社”;“PDI”;“全球人民地位”;“术语词汇表”
“德国劳埃德船级社”;“PDI”;“全球人民地位”;“人员状态全局更新”
“德国劳埃德船级社”;“GLB”;“全球人民地位”;“术语词汇表”
“德国劳埃德船级社”;“GLB”;“全球人民地位”;“人员状态全局更新”
“德国劳埃德船级社”;“GLB”;“全球人民地位”;“术语词汇表”
“德国劳埃德船级社”;“GLB”;“全球人民地位”;“人员状态全局更新”
“FTR”;12
使用我的xsl,我只得到一行:
“德国劳埃德船级社”;“PDAPDIGLB”;“人员状态全球人员状态”;“术语词汇人员状态全局更新” 和标题行:
“人类发展报告”;“PIGLSSTD”;"20120112045620";“F”:
应在开头追加一行页脚
“FTR”
在底部。您想要这样的东西:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:defaults>
<termCat/>
<termVocab/>
</my:defaults>
<xsl:variable name="vDefaults" select="document('')/*/my:defaults"/>
<xsl:variable name="vQ">"</xsl:variable>
<xsl:template match="term">
<xsl:variable name="vTerm" select="."/>
<xsl:variable name="vRow1" select="'
"GL";'"/>
<xsl:for-each select=
"termCategory
|
$vDefaults/termCat[not($vTerm/termCategory)]">
<xsl:variable name="vRow2" select=
"concat($vRow1, $vQ, ., $vQ, ';')"/>
<xsl:for-each select=
"$vTerm/termVocabulary
|
$vDefaults/termCat[not($vTerm/termVocabulary)]
">
<xsl:variable name="vRow3" select=
"concat($vRow2, $vQ, ., $vQ, ';')"/>
<xsl:for-each select=
"$vTerm/relation/termVocabulary
|
$vDefaults/termCat[not($vTerm/relation/termVocabulary)]
">
<xsl:value-of select="concat($vRow3, $vQ, ., $vQ, ';')"/>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
<GetSavedReportResponse>
<ResponseType>Success</ResponseType>
<FileModifiedDateTime>2012-01-03T17:05:04</FileModifiedDateTime>
<FileSizeBytes>7816</FileSizeBytes>
<FileDataFormat>XML</FileDataFormat>
<FileData>
<Zthes>
<term>
<termId>49555</termId>
<termUpdate>add</termUpdate>
<termName>Active Personnel</termName>
<termVocabulary>People Status Global</termVocabulary>
<termVocabulary>Global People Status</termVocabulary>
<termCategory>PDA</termCategory>
<termCategory>PDI</termCategory>
<termCategory>GLB</termCategory>
<relation weight="100">
<termId>49556</termId>
<relationType>EQ</relationType>
<termName>term name</termName>
<termVocabulary>term vocabulary</termVocabulary>
</relation>
<relation weight="100">
<termId>49557</termId>
<relationType>BT</relationType>
<termName>General Active Personnel</termName>
<termVocabulary>People Status Global Updated</termVocabulary>
</relation>
</term>
<term>
<termId>49556</termId>
<termUpdate>add</termUpdate>
<termName>Leave of Absence Personnel</termName>
<termVocabulary>People Status Global</termVocabulary>
<termCategory>GLB</termCategory>
<termCategory>PDI</termCategory>
<relation weight="100">
<relationType>BT</relationType>
<termId>49554</termId>
<termName>General Non-Active Personnel</termName>
<termVocabulary>People Status Global</termVocabulary>
</relation>
</term>
</Zthes>
</FileData>
</GetSavedReportResponse>
"GL";"PDA";"People Status Global";"term vocabulary";
"GL";"PDA";"People Status Global";"People Status Global Updated";
"GL";"PDA";"Global People Status";"term vocabulary";
"GL";"PDA";"Global People Status";"People Status Global Updated";
"GL";"PDI";"People Status Global";"term vocabulary";
"GL";"PDI";"People Status Global";"People Status Global Updated";
"GL";"PDI";"Global People Status";"term vocabulary";
"GL";"PDI";"Global People Status";"People Status Global Updated";
"GL";"GLB";"People Status Global";"term vocabulary";
"GL";"GLB";"People Status Global";"People Status Global Updated";
"GL";"GLB";"Global People Status";"term vocabulary";
"GL";"GLB";"Global People Status";"People Status Global Updated";
"GL";"GLB";"People Status Global";"People Status Global";
"GL";"PDI";"People Status Global";"People Status Global";
解释:仅当形成完整的行时才进行输出,而不是在此之前
更新:OP在禁用document()
功能的环境中工作。他还想要一个页眉和页脚
在这种情况下,现在可以使用稍加修改的转换(使用exslt:node-set()
扩展函数):
"
HDR”;“PIGLSSTD”;"20120112045620";“F”:
;FTR
谢谢迪米特里·诺瓦切夫。当至少有一个术语类别/术语词汇表/关系时,它可以正常工作。但是,当任何一个标记不存在时(例如:没有词汇表标记,2个类别标记,1个关系),我们就不会得到整个术语的任何行。对于上面的术语,我必须得到两行空字符串来代替术语词汇表。@user1147759:我已经更新了我的解决方案以实现您的新要求。但是,我没有得到类似以下术语的行:49555添加现役人员PDI术语1 GLB术语1 49556 EQ术语1术语名称术语1术语词汇术语1,其中我应该得到2行带“”的VOC请编辑并更新问题。注释中的代码不可读。很抱歉,由于“禁止执行”document()“函数而失败。使用XsltSettings.EnableDocumentFunction属性启用它。'错误。我应该如何启用它,或者我们可以在没有document()的情况下使用xsl?您正在混合使用每个和模板。选择一种方法并坚持下去。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vrtfDefaults">
<termCat/>
<termVocab/>
</xsl:variable>
<xsl:variable name="vDefaults" select=
"ext:node-set($vrtfDefaults)"/>
<xsl:variable name="vQ">"</xsl:variable>
<xsl:template match="Zthes">
<xsl:text>HDR";"PIGLSSTD";"20120112045620";"F":</xsl:text>
<xsl:apply-templates/>
<xsl:text>
FTR</xsl:text>
</xsl:template>
<xsl:template match="term">
<xsl:variable name="vTerm" select="."/>
<xsl:variable name="vRow1" select="'
"GL";'"/>
<xsl:for-each select=
"termCategory
|
$vDefaults/termCat[not($vTerm/termCategory)]">
<xsl:variable name="vRow2" select=
"concat($vRow1, $vQ, ., $vQ, ';')"/>
<xsl:for-each select=
"$vTerm/termVocabulary
|
$vDefaults/termCat[not($vTerm/termVocabulary)]
">
<xsl:variable name="vRow3" select=
"concat($vRow2, $vQ, ., $vQ, ';')"/>
<xsl:for-each select=
"$vTerm/relation/termVocabulary
|
$vDefaults/termCat[not($vTerm/relation/termVocabulary)]
">
<xsl:value-of select="concat($vRow3, $vQ, ., $vQ, ';')"/>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>