选择属性的所有值并使用 XSLT 1.0 作为列表返回

Posted

技术标签:

【中文标题】选择属性的所有值并使用 XSLT 1.0 作为列表返回【英文标题】:Select all values of an attribute and return as list using XSLT 1.0 【发布时间】:2020-11-11 23:09:21 【问题描述】:

我有一个包含多个递归属性的 XML 文档:

<?xml version="1.0" encoding="UTF-8"?>
<d2LogicalModel xmlns="http://datex2.eu/schema/2/2_0" modelBaseVersion="2"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <publicationTime>2020-04-21T12:31:11.651Z</publicationTime>
        <situation id="1234" version="5">
            <someRecord>value</someRecord>
            <situationRecord xsi:type="Type1" id="type1_id_001" version="01">
                <situationRecordCreationTime>2020-03-16T14:59:30Z</situationRecordCreationTime>
            </situationRecord>
            <situationRecord xsi:type="Type1" id="type1_id_002" version="01">
                <situationRecordCreationTime>2020-03-16T14:59:30Z</situationRecordCreationTime>
            </situationRecord>
            <situationRecord xsi:type="Type2" id="type2_id_001" version="01">
                <situationRecordCreationTime>2020-03-16T14:59:30Z</situationRecordCreationTime>
                <attributes>
                    <att>attribute1</att>
                    <att>attribute2</att>
                    <att>attribute3</att>
                    <attUsage>attribute1Usage</attUsage>
                </attributes>
            </situationRecord>
        </situation>
</d2LogicalModel>

因此可以有 1 个或多个 situation 元素,每个元素包含一个或多个 situationRecord 元素。 我想提取一些属性并将其转换为 Python 字典。我因此使用以下 XSL:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:pub="http://datex2.eu/schema/2/2_0"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/">
        <!--predefined separator for further use-->
        <xsl:variable name="sep" select="','"/>
        <!--set column names-->
        <xsl:value-of select="concat('situation_id', $sep,
                              'situation_version', $sep,
                            'situation_record_id', $sep,
                       'situation_record_version', $sep,
                          'situation_record_type', $sep,
                 'situation_record_creation_time', $sep,
                                     'attributes', '&#xa;')"/>

        <!--predefined separator for further use-->
        <xsl:for-each select="//pub:situation">
            <!--get ids for each further record-->
            <xsl:variable name="ref.id" select="@id"/>
            <xsl:variable name="ref.version" select="@version"/>

            <xsl:for-each select="pub:situationRecord">
                <!--get all required values in variables for further result concat-->
                <xsl:variable name="pub.time" select="ancestor::pub:payloadPublication/pub:publicationTime"/>
                <xsl:variable name="id" select="@id"/>
                <xsl:variable name="version" select="@version"/>
                <xsl:variable name="type" select="@xsi:type"/>
                <xsl:variable name="situationRecordCreationTime" select="pub:situationRecordCreationTime"/>
                <xsl:variable name="attributes" select="concat(pub:attributes/pub:att,'-')"/>

                <!--getting result with concat function-->
                <xsl:value-of select="concat($ref.id, $sep,
                                        $ref.version, $sep,
                                                 $id, $sep,
                                            $version, $sep,
                                               $type, $sep,
                        $situationRecordCreationTime, $sep,
                                         $attributes, '&#xa;')"/>

            </xsl:for-each>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

这适用于除attributes 元素之外的所有元素。我想选择所有 att 元素值并将其作为逗号分隔的列表或字符串返回。

所需输出:attribute1,attribute2,attribute3

我可以使用以下方法从 attributes 元素中获取所有值作为字符串:

<xsl:variable name="attributes" select="pub:attributes"/>

返回attribute1attribute2attribute3attribute1Usage。这也返回了 attUsage 值,不应该是这种情况。

或使用:

<xsl:variable name="attributes" select="concat(pub:attributes/pub:att,'-')"/>

只返回attribute1-

如何使用 XSLT 1.0 解决这个问题?

【问题讨论】:

【参考方案1】:

您必须遍历元素并使用所需的分隔符输出它们:

您可以在转换中替换此行:

<xsl:variable name="attributes" select="concat(pub:attributes/pub:att,'-')"/>

通过这个:

            <xsl:variable name="attributes">
                <xsl:for-each select="pub:attributes/pub:att">
                  <xsl:value-of select="."/>
                  <xsl:if test="position()!=last()">
                    <xsl:value-of select="'-'"/>
                  </xsl:if>
                </xsl:for-each>
            </xsl:variable>

【讨论】:

谢谢!我将如何在我当前的 XSL 结构中实现它?我需要 xsl:variable 名称中的输出,以便在我的列名中使用它。

以上是关于选择属性的所有值并使用 XSLT 1.0 作为列表返回的主要内容,如果未能解决你的问题,请参考以下文章

获取元素的值并使其成为 XSLT 中属性的值?

XSLT - 如何仅输出属性值并忽略元素的值

基于列表中的日期字段,在每一天对使用XSLT 1.0的列表进行分组

XSLT - 使用隧道传递变量未按预期工作

是否可以使用 XSLT 1.0 对条目进行分组?

不在运动列表中的所有学生的 xslt 输出