用于嵌套父元素的 XSLT

XSLT for nested parent elements

我是 XSLT 的新手,我有一个 XML 文件,我正试图将其转换为“|”使用 XSLT 分隔的 CSV。 CSV中有一个单元格值需要通过循环遍历TPFC下的当前节点和父节点并将所有名称连接为单个名称来计算 (注意:父嵌套可以是一个也可以是多个,这里我的例子有2个父嵌套)

例如,下面 XML 的名称将是 AM_Mob1_Mob2

<?xml version="1.0" encoding="UTF-8"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Package ID="1122" BusinessID="001233" Version="19.0.2" xsi:type="Doms">
    <Name>ABC</Name>
    <Description> Desc sample</Description>
    <Category>54</Category>
    <Business_ID>001233</Business_ID>

    <TPFC ID="76" xsi:type="TPFC" Pattern="Th_Branch">
        <Name>AM</Name>
        <Parent ID="11d" xsi:type="TPFC" Pattern="Th_Branch">
            <Description>Mob1</Description>
            <Name>Mob1</Name>
            <Parent ID="12F" xsi:type="TPFC" Pattern="Th_Branch">
            <Description>Mob2</Description>
            <Name>Mob2</Name>
            </Parent>
        </Parent>
    </TPFC>
</Package>

我尝试了 params 方法,我不确定这是否是正确的方法,但无论如何,当我尝试下面的代码片段时我没有得到输出

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" >
<xsl:output method="text" encoding="utf-8"/>
<!--  Delimiter  -->
<xsl:variable name="separator" select="'|'"/>
<xsl:template match="/">
<xsl:for-each select="//TPFC ">
           <!--Nesting logic ends here-->
           <xsl:param name="Concatvar">
           <xsl:for-each select="Parent/Name">
           <xsl:if test="Parent/Name">
           <xsl:value-of select="concat($Concatvar,Parent/Name/text())"/>
           </xsl:if>
           </xsl:for-each>
           </xsl:param>
            <xsl:value-of select="$Concatvar"/>
            <xsl:value-of select="$separator"/>
            <--Nesting logic ends here--!>
            <xsl:value-of select="normalize-space(Name)"/>
            <xsl:value-of select="$separator"/>
            <xsl:value-of select="normalize-space(Description)"/>
            <xsl:value-of select="$separator"/>
            <xsl:value-of select="normalize-space(Parent/Name)"/>
</xsl:template>

谁能告诉我为这个预期结果编写 XSLT 的正确方法是什么

  | id           | name | description | parent_name | parent_id   | level | total_level | product_offering_id | 
  | AM_Mob1_Mob2 | AM   | Desc Sample | Mob1        | Mob1_Mob2_ | 2     | 3           | 001233              | 

id - 在以下示例中将所有名称连接到其根父级 它将是 AM_Mob1_Mob2

level - 如果有两个级别,child 是 level 2,parent 是 level 1

total_level - 来自 TPFC + 1 的树的深度,即产品系列层次结构中的 no.of 个级别

这种事情在 XSLT 2.0 或 3.0 中要容易得多(但较旧的 XSLT 处理器仅支持 1.0)。您的样式表指定了 version="2.0",但您没有标记 xslt-2 问题,所以我假设您可以使用 XSLT 2.0。

在2.0中你可以通过写

来实现需要的输出
<xsl:value-of select="Name, Parent/Name" separator="_"/>

在 1.0 中,您需要类似于当前逻辑的东西,但请注意 (a) 您应该使用 xsl:variable 而不是 xsl:param,并且 (b) 在 xsl:for-each 内,上下文项发生变化,因此在 <xsl:for-each select="Parent/Name"> 内你应该 select .,而不是 Parent/Name.

恐怕这里需要应用的逻辑还不够清晰。

看看这是否可以帮助您入门:

XSLT 2.0

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

<xsl:template match="/Root">
    <!-- header -->
    <xsl:text>id|name|description|parent_name|parent_id|... &#10;</xsl:text>
    <!-- data -->
    <xsl:for-each select="Package">
        <xsl:variable name="pkg-desc" select="Description" />
        <xsl:variable name="b-id" select="Business_ID" />
        <!-- TPFC data -->
        <xsl:for-each select="TPFC">
            <xsl:value-of select="Name, .//Parent/Name" separator="_"/>
            <xsl:text>|</xsl:text>
            <xsl:value-of select="Name"/>
            <xsl:text>|</xsl:text>
            <xsl:value-of select="$pkg-desc"/>
            <xsl:text>|</xsl:text>
            <!-- parent data -->
            <xsl:value-of select="Parent/Name"/>
            <xsl:text>|</xsl:text>
            <xsl:value-of select=".//Parent/Name" separator="_"/>
            <xsl:text>|</xsl:text>
            <!-- ??? -->

        </xsl:for-each>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each> 
</xsl:template>

</xsl:stylesheet>

应用于提供的输入示例,结果将是:

id|name|description|parent_name|parent_id|... 
AM_Mob1_Mob2|AM| Desc sample|Mob1|Mob1_Mob2|