XSLT 到 CSV - 如何控制具有不同属性值的同一元素的顺序?
XSLT to CSV - How to control the order of the same element with different attribute values?
我是 XSLT 的新手,我需要弄清楚如何根据 CSV 文件的属性值以特定顺序从 XML 文件中检索重复元素。我的结果文档是一个 CSV 文件,我最终需要将其内容导入 SQL 服务器 tables。因此,CSV 文件中检索到的元素的顺序很重要,因为它们需要匹配定义为 headers.
的 table 列
我的问题出现在 Project Content_Detail 元素中,该元素以不同的语言存在并且可以以任何顺序出现在 XML 源代码中。我只需要首先提取带有 Title, Goal 元素的德文版本,然后是英文版本元素。
我使用 SSIS 和 MS Visual Studio 2019 将我的 XML 转换为 CSV 文件。 MS Visual Studio 仅支持 XSLT 1.0。
这是我的 XML 文件(已编辑):
<?xml version="1.0" encoding="utf-8"?>
<dta:Projects xmlns:dta="http://domain.test/dta">
<dta:Project>
<dta:Core-Basis>
<dta:Goal>1672</dta:Goal>
</dta:Core-Basis>
<dta:Basisinfo>
<dta:Content>
<dta:Content_Detail Lang="de">
<dta:Title>Wirtschaft</dta:Title>
<dta:Aim>Steigerung</dta:Aim>
</dta:Content_Detail>
<dta:Content_Detail Lang="en">
<dta:Title>Economy</dta:Title>
</dta:Content_Detail>
</dta:Content>
</dta:Basisinfo>
</dta:Project>
<dta:Project >
<dta:Core-Basis>
<dta:Goal>2035</dta:Goal>
</dta:Core-Basis>
<dta:Basisinfo>
<dta:Content>
<dta:Content_Detail Lang="en">
<dta:Title>Environmental Protection</dta:Title>
<dta:Aim>Facilitation</dta:Aim>
</dta:Content_Detail>
<dta:Content_Detail Lang="de">
<dta:Title>Naturschutz</dta:Title>
</dta:Content_Detail>
</dta:Content>
</dta:Basisinfo>
</dta:Project >
</dta:Projects>
这是我的 XSLT 文件(已编辑)。我尝试向 xsl:if 块添加大量顺序和排序参数,但我还没有想出一个可行的解决方案:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dta="http://domain.test/dta" exclude-result-prefixes="dta">
<xsl:output method="text" encoding="UTF-8" indent="no"/>
<xsl:template match="/">
<xsl:text>DTA_Goal;DTA_Title_de;DTA_Aim_de;DTA_Title_en;DTA_Aim_en;
</xsl:text>
<xsl:apply-templates mode="find_content"/>
</xsl:template>
<xsl:template match="text()|@*" mode="find_content"/>
<xsl:template match="dta:Project" mode="find_content">
<xsl:value-of select="concat(dta:Core-Basis/dta:Goal,';')"/>
<xsl:apply-templates mode="find_content"/>
</xsl:template>
<xsl:template match="dta:Content_Detail" mode="find_content">
<xsl:if test="@Lang='de'">
<xsl:value-of select="concat(dta:Title,';')"/>
<xsl:value-of select="concat(dta:Aim,';')"/>
</xsl:if>
<xsl:if test="@Lang='en'">
<xsl:value-of select="concat(dta:Title,';')"/>
<xsl:value-of select="concat(dta:Aim,'
')"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
这是我到目前为止的 CSV 输出,没有根据语言值属性对 Content_detail 进行排序:
DTA_Goal;DTA_Title_de;DTA_Aim_de;DTA_Title_en;DTA_Aim_en;
1672;Wirtschaft;Steigerung;Economy;
2035;Environmental Protection;Facilitation
Naturschutz;;
这是我需要的:
DTA_Goal; DTA_Title_de; DTA_Aim_de; DTA_Title_en; DTA_Aim_en;
1672;Wirtschaft;Steigerung;Economy;;
2035;Naturschutz;;Environmental Protection;Facilitation;
由于我不是专业程序员,因此非常感谢对我的其余代码的任何帮助或评论。
在您的输入中,dta:Project
个元素之一有一个 dta:Core-Basis
个子元素,而另一个元素有 dta:Core-Basisdaten
个。假设这是一个错误*,您可以简单地通过以下方式生成所需的输出:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dta="http://domain.test/dta">
<xsl:output method="text" encoding="UTF-8" />
<xsl:template match="/dta:Projects">
<!-- header -->
<xsl:text>DTA_Goal;DTA_Title_de;DTA_Aim_de;DTA_Title_en;DTA_Aim_en; </xsl:text>
<!-- data -->
<xsl:for-each select="dta:Project">
<xsl:value-of select="dta:Core-Basis/dta:Goal"/>
<xsl:text>;</xsl:text>
<!-- de -->
<xsl:variable name="content-de" select="dta:Basisinfo/dta:Content/dta:Content_Detail[@Lang='de']" />
<xsl:value-of select="$content-de/dta:Title"/>
<xsl:text>;</xsl:text>
<xsl:value-of select="$content-de/dta:Aim"/>
<xsl:text>;</xsl:text>
<!-- en -->
<xsl:variable name="content-en" select="dta:Basisinfo/dta:Content/dta:Content_Detail[@Lang='en']" />
<xsl:value-of select="$content-en/dta:Title"/>
<xsl:text>;</xsl:text>
<xsl:value-of select="$content-en/dta:Aim"/>
<xsl:text>;</xsl:text>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
(*) 如果不是,则更改:
<xsl:value-of select="dta:Core-Basis/dta:Goal"/>
至:
<xsl:value-of select="(dta:Core-Basis|dta:Core-Basisdaten)/dta:Goal"/>
P.S。不确定为什么需要在每行末尾添加 ;
。
我是 XSLT 的新手,我需要弄清楚如何根据 CSV 文件的属性值以特定顺序从 XML 文件中检索重复元素。我的结果文档是一个 CSV 文件,我最终需要将其内容导入 SQL 服务器 tables。因此,CSV 文件中检索到的元素的顺序很重要,因为它们需要匹配定义为 headers.
的 table 列我的问题出现在 Project Content_Detail 元素中,该元素以不同的语言存在并且可以以任何顺序出现在 XML 源代码中。我只需要首先提取带有 Title, Goal 元素的德文版本,然后是英文版本元素。
我使用 SSIS 和 MS Visual Studio 2019 将我的 XML 转换为 CSV 文件。 MS Visual Studio 仅支持 XSLT 1.0。
这是我的 XML 文件(已编辑):
<?xml version="1.0" encoding="utf-8"?>
<dta:Projects xmlns:dta="http://domain.test/dta">
<dta:Project>
<dta:Core-Basis>
<dta:Goal>1672</dta:Goal>
</dta:Core-Basis>
<dta:Basisinfo>
<dta:Content>
<dta:Content_Detail Lang="de">
<dta:Title>Wirtschaft</dta:Title>
<dta:Aim>Steigerung</dta:Aim>
</dta:Content_Detail>
<dta:Content_Detail Lang="en">
<dta:Title>Economy</dta:Title>
</dta:Content_Detail>
</dta:Content>
</dta:Basisinfo>
</dta:Project>
<dta:Project >
<dta:Core-Basis>
<dta:Goal>2035</dta:Goal>
</dta:Core-Basis>
<dta:Basisinfo>
<dta:Content>
<dta:Content_Detail Lang="en">
<dta:Title>Environmental Protection</dta:Title>
<dta:Aim>Facilitation</dta:Aim>
</dta:Content_Detail>
<dta:Content_Detail Lang="de">
<dta:Title>Naturschutz</dta:Title>
</dta:Content_Detail>
</dta:Content>
</dta:Basisinfo>
</dta:Project >
</dta:Projects>
这是我的 XSLT 文件(已编辑)。我尝试向 xsl:if 块添加大量顺序和排序参数,但我还没有想出一个可行的解决方案:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dta="http://domain.test/dta" exclude-result-prefixes="dta">
<xsl:output method="text" encoding="UTF-8" indent="no"/>
<xsl:template match="/">
<xsl:text>DTA_Goal;DTA_Title_de;DTA_Aim_de;DTA_Title_en;DTA_Aim_en;
</xsl:text>
<xsl:apply-templates mode="find_content"/>
</xsl:template>
<xsl:template match="text()|@*" mode="find_content"/>
<xsl:template match="dta:Project" mode="find_content">
<xsl:value-of select="concat(dta:Core-Basis/dta:Goal,';')"/>
<xsl:apply-templates mode="find_content"/>
</xsl:template>
<xsl:template match="dta:Content_Detail" mode="find_content">
<xsl:if test="@Lang='de'">
<xsl:value-of select="concat(dta:Title,';')"/>
<xsl:value-of select="concat(dta:Aim,';')"/>
</xsl:if>
<xsl:if test="@Lang='en'">
<xsl:value-of select="concat(dta:Title,';')"/>
<xsl:value-of select="concat(dta:Aim,'
')"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
这是我到目前为止的 CSV 输出,没有根据语言值属性对 Content_detail 进行排序:
DTA_Goal;DTA_Title_de;DTA_Aim_de;DTA_Title_en;DTA_Aim_en;
1672;Wirtschaft;Steigerung;Economy;
2035;Environmental Protection;Facilitation
Naturschutz;;
这是我需要的:
DTA_Goal; DTA_Title_de; DTA_Aim_de; DTA_Title_en; DTA_Aim_en;
1672;Wirtschaft;Steigerung;Economy;;
2035;Naturschutz;;Environmental Protection;Facilitation;
由于我不是专业程序员,因此非常感谢对我的其余代码的任何帮助或评论。
在您的输入中,dta:Project
个元素之一有一个 dta:Core-Basis
个子元素,而另一个元素有 dta:Core-Basisdaten
个。假设这是一个错误*,您可以简单地通过以下方式生成所需的输出:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:dta="http://domain.test/dta">
<xsl:output method="text" encoding="UTF-8" />
<xsl:template match="/dta:Projects">
<!-- header -->
<xsl:text>DTA_Goal;DTA_Title_de;DTA_Aim_de;DTA_Title_en;DTA_Aim_en; </xsl:text>
<!-- data -->
<xsl:for-each select="dta:Project">
<xsl:value-of select="dta:Core-Basis/dta:Goal"/>
<xsl:text>;</xsl:text>
<!-- de -->
<xsl:variable name="content-de" select="dta:Basisinfo/dta:Content/dta:Content_Detail[@Lang='de']" />
<xsl:value-of select="$content-de/dta:Title"/>
<xsl:text>;</xsl:text>
<xsl:value-of select="$content-de/dta:Aim"/>
<xsl:text>;</xsl:text>
<!-- en -->
<xsl:variable name="content-en" select="dta:Basisinfo/dta:Content/dta:Content_Detail[@Lang='en']" />
<xsl:value-of select="$content-en/dta:Title"/>
<xsl:text>;</xsl:text>
<xsl:value-of select="$content-en/dta:Aim"/>
<xsl:text>;</xsl:text>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
(*) 如果不是,则更改:
<xsl:value-of select="dta:Core-Basis/dta:Goal"/>
至:
<xsl:value-of select="(dta:Core-Basis|dta:Core-Basisdaten)/dta:Goal"/>
P.S。不确定为什么需要在每行末尾添加 ;
。