唯一排序节点之前的 XSL 计数

     2023-02-16     283

关键词:

【中文标题】唯一排序节点之前的 XSL 计数【英文标题】:XSL count preceding unique sorted nodes 【发布时间】:2013-12-06 13:20:52 【问题描述】:

我有一个相当复杂的 XSL 任务。我有一个类似的 XML 文档

<authorlist>
    <orgs>
        <org id="org1" name="Org A"/>
        <org id="org2" name="Org B"/>
        <org id="org3" name="Org C"/>
    </orgs>
    <authors>
        <auth name="C. Thor">
            <affiliations>
                <affil id="org2"/>
                <affil id="org3"/>
            </affiliations>
        </auth>
        <auth name="A. Thor">
            <affiliations>
                <affil id="org3"/>
            </affiliations>
        </auth>
        <auth name="B. Thor">
            <affiliations>
                <affil id="org1"/>
            </affiliations>
        </auth>
    </authors>
</authorlist>

我想编写一个 XSL 转换,它将产生以下(文本)输出

1 Org C
2 Org A
3 Org B

A. Thor ^1
B. Thor ^2
C. Thor ^1,3

也就是说,作者按姓名字母顺序排序。每个作者的名字都被打印出来,以及表明她的隶属关系的上标。组织按照它们在作者排序列表中首次出现的顺序打印。每个作者可能有多个隶属关系。

这是我认为我需要做的:

    创建一个从组织映射到序数的键,以便我可以正确地对组织进行排序(并将正确的上标放在作者姓名上)。我相信我知道该怎么做。 要创建该密钥,我需要计算与当前(创建密钥时)组织有关联的作者的第一个实例之前的唯一作者隶属关系的数量。我想我知道该怎么做。 关键是如何定义“在前”和“在前”。如果我理解正确,“preceding”和“first”是由文档顺序定义的,或者可能是由一些模糊的 XPath“处理顺序”定义的。我非常需要通过按作者姓名字母顺序对作者进行排序来定义“在先”和“第一”。我不知道如何做到这一点,甚至不知道这是否可能。

我可以使用的 XSLT 处理器是 xsltproc,它实现了 XSLT 1.0。如果有足够令人信服的案例,我可以考虑提供不同的处理器,但我能否使用不同的处理器有点怀疑。

现实世界的情况会变得更加复杂,因为有些组织有多个子组织,而且还有两类组织,成员组织和访客组织,它们打印在单独的列表中,并且具有独立的顺序他们的上标。但是,我认为解决上述问题就足够了。

【问题讨论】:

您能解释一下A. Thor ^1 究竟是如何组合在一起的吗? 1 代表什么,我不确定我是否理解。 (我猜它指的是org3,因为如果您按姓名对作者进行排序,那将是第一个组织。对吧?) A. Thor 隶属于 org3 (Org C)。由于 A. Thor 是第一个(按字母顺序)作者,而 org3 是 A. Thor 的第一个隶属关系,所以 org3 获得索引 1。所以,我们有 A. Thor ^1,表明 A. Thor 隶属于具有索引的组织1,即 Org C。这很令人困惑,这可能是我为之苦苦挣扎的原因。 组织 C 是如何获得索引 1 的?您的示例中没有任何内容暗示这一点。另外,到目前为止,您尝试过什么?请发布您现有的作品并解释为什么它不能满足您的需求。 Org C 的索引为 1,因为它是第一作者的第一个单位。正如我在原文中所说,“组织按照它们首先出现在作者排序列表中的顺序打印。”我应该更清楚地说明,“组织按照它们在作者排序列表中首次出现的顺序进行索引,并且按照它们的索引顺序打印。” 【参考方案1】:

一种方法:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" />

  <xsl:variable name="orgIndex">
    <xsl:apply-templates select="//authors/auth" mode="orgIdx">
      <xsl:sort select="@name" />
    </xsl:apply-templates>
  </xsl:variable>

  <xsl:template match="authorlist">
    <xsl:apply-templates select="authors" />
  </xsl:template>

  <xsl:template match="authors">
    <xsl:apply-templates select="auth">
      <xsl:sort select="@name" />
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="auth">
    <xsl:value-of select="@name" />
    <xsl:text> ^</xsl:text>
    <xsl:apply-templates select="affiliations/affil" mode="orgIdx">
      <xsl:sort select="string-length(substring-before($orgIndex, @id))" data-type="number" />
    </xsl:apply-templates>
    <xsl:text></xsl:text>
    <xsl:if test="position() &lt; last()">
      <xsl:value-of select="'&#xA;'" />
    </xsl:if>
  </xsl:template>

  <xsl:template match="affil" mode="orgIdx">
    <xsl:variable name="str" select="substring-before($orgIndex, @id)" />
    <xsl:variable name="idx" select="string-length($str) - string-length(translate($str, '|', ''))" />
    <xsl:value-of select="$idx" />
    <xsl:if test="position() &lt; last()">,</xsl:if>
  </xsl:template>

  <xsl:template match="auth" mode="orgIdx">
    <xsl:for-each select="affiliations/affil">
      <xsl:value-of select="concat('|', @id)" /> 
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

结果

A. 雷神 ^1 B. 雷神 ^2 C. 雷神 ^1,3

此方法基于以正确的顺序(即按名称字母顺序按auth,按文档顺序在auth 内)构建一个分隔字符串affil/@id

对于您的示例,字符串 $orgIndex 将是 '|org3|org1|org2|org3'

@ids 将在该字符串中重复,但这没关系,因为我们不关心字符串的后部。

现在我们可以使用substring-before() 来确定第一次出现 ID 之前的分隔字符数,这会导致您似乎正在寻找数字索引。

【讨论】:

这很丑,但它有效,所以我不在乎它有多丑。需要进行一项更改:xsl:sort 需要一个附加属性 data-type="number"。 这个特殊问题可能没有真正漂亮的解决方案。 粗鲁。这有一个问题,即如果字符串$orgIndex'|org3|org3|org1|org2|org3',那么'org1' 将被赋予索引3 和'org2' 索引4。我的真实世界作者列表大约有60 个组织和400 人,并且组织指数最多为 488!我正在努力寻找解决方案。此外,有些组织的id 是另一个组织的id 的子字符串(例如'org1''org10')。不过,我认为那里的解决方案很简单,只需在id 的适当末尾添加一个分隔符即可。

仅针对 XSL 1.0 中的特定条件列出组内属性的唯一值

】仅针对XSL1.0中的特定条件列出组内属性的唯一值【英文标题】:ListuniquevaluesofanattributewithinagrouponlyforspecificcriteriainXSL1.0【发布时间】:2015-09-0601:45:46【问题描述】:当另一个属性具有特定值时,我需要列出组中某个属性的唯一... 查看详情

使用 `<xsl:apply-templates>` 排序后缺少一些子节点

】使用`<xsl:apply-templates>`排序后缺少一些子节点【英文标题】:Missingsomechildnodesaftersortingwith`<xsl:apply-templates>`【发布时间】:2021-03-1508:26:58【问题描述】:我正在尝试根据字段start_date对子节点进行排序。在下面的XML节点... 查看详情

XSL FO 在具体注释之后读取第一个 fo:table 节点

...有多个嵌套的fo:table对象,并且所有这些对象都不是通过唯一的id属性来标识的,以允许通过其唯一的Id搜索每个对象。每个fo:table的开头都有一 查看详情

XSL:在 XSL 1.0 中组合两个节点集

】XSL:在XSL1.0中组合两个节点集【英文标题】:XSL:CombiningTwoNodeSetsinXSL1.0【发布时间】:2013-06-0902:03:09【问题描述】:我将在此之前说明我是XSLT(在本例中为1.0)的新手,并且我自己解决这个问题的运气很差。我有以下XML:<Ro... 查看详情

用于排序和获取唯一计数的 SQL 查询

】用于排序和获取唯一计数的SQL查询【英文标题】:SQLQueryforsortingandgettinguniquecount【发布时间】:2021-03-2800:53:33【问题描述】:我有一张包含以下详细信息的表格CustomerDealDealStageAD1LostAD2WonAD3ContactedBD4ConatctedBD5LostCD6LostDD7Lost我必... 查看详情

使用xsl:排序到按子字符串对输出节点排序

<!-- ThestylesheetwilltransformthisXMLdocument: <doc><SortPrefixAndTitle>3|ThirdCourse</SortPrefixAndTitle><SortPrefixAndTitle>1|FirstCourse</SortPrefixAndTitle><SortPrefixAndTitle>2|SecondCourse</SortPrefixAndTitle></doc> into: ... 查看详情

获取数据框中列的唯一值的计数,这些值最终出现在决策树的每个叶节点中?

】获取数据框中列的唯一值的计数,这些值最终出现在决策树的每个叶节点中?【英文标题】:GettingacountofuniquevaluesforacolumnindataframethatendupineachleafnodeofDecisionTree?【发布时间】:2020-09-1421:42:04【问题描述】:我正在数据框上构建... 查看详情

XSL 位置计数不正确

】XSL位置计数不正确【英文标题】:XSLPositiondoesn\'tcountcorrectly【发布时间】:2021-11-2520:09:30【问题描述】:我已经尝试了几天来解决这个XML转换问题。我需要通过XSLT文件将带有序号的“标识符”属性添加到XML标记中。我需要指... 查看详情

XSL:根据属性计数和匹配创建组

】XSL:根据属性计数和匹配创建组【英文标题】:XSL:Creategroupbasedonattributecountandmatch【发布时间】:2019-08-3109:06:36【问题描述】:当属性的计数=X和基于属性值的第二组时,我试图插入一个容器。这两个属性不相关。使用XSLT-V1我... 查看详情

从 XSL 中的命名空间节点获取子节点

】从XSL中的命名空间节点获取子节点【英文标题】:GettingchildfromanamespacednodeinXSL【发布时间】:2018-08-0821:07:41【问题描述】:我需要获取c:batch节点的每个子节点。与节点不匹配。我做错了什么?任何帮助表示赞赏。提前致谢。&l... 查看详情

使用 xsl:number 递减变量计数器

】使用xsl:number递减变量计数器【英文标题】:Descendvariablecounterusingxsl:number【发布时间】:2021-11-0913:25:23【问题描述】:我希望使用变量来获得需要按后代顺序计算的日期,例如(2021年1月1日,2020年1月1日)。我已经简化了代码... 查看详情

XSLT:使用输入 XML 中的唯一且已排序的日期创建新的 XML 节点

】XSLT:使用输入XML中的唯一且已排序的日期创建新的XML节点【英文标题】:XSLT:CreatenewXMLnodewithuniqueandsorteddatesfrominputXML【发布时间】:2021-10-3020:53:45【问题描述】:我已经为此搜索了各种其他帖子,但到目前为止还没有得到这... 查看详情

如何使用 XSL 选择特定元素节点中的所有文本节点?

】如何使用XSL选择特定元素节点中的所有文本节点?【英文标题】:HowdoiselectallthetextnodeswithinaspecificelementnodeusingXSL?【发布时间】:2011-02-2422:02:48【问题描述】:如何使用XSL选择特定元素节点内的所有文本节点?输入xml:<node1i... 查看详情

XSL 节点集:不按名称查找子元素

】XSL节点集:不按名称查找子元素【英文标题】:XSLnodeset:donotfindchildelementsbyname【发布时间】:2019-01-1803:42:18【问题描述】:我是xsl的初学者,所以也许这是一个非常简单的问题。我有一个xsl文件,我想在其中找到在param-object中... 查看详情

fp-growth算法

...2.将计数(频度)低于最小值的过滤掉,将剩下的一项集排序(降序)3.参照排序后的一项集将初始的数据集依次排序4.将排好序的数据集从根节点开始建树,根节点初始化为空5.建树的过程中对经过的节点进行计数,得到节点带... 查看详情

拓扑排序(代码片段)

拓扑排序1.存储结构?采用邻接表,在表节点中增加degree域,记录每个节点的入度。2.实现步骤?1.先求每个节点的入度?2.借助栈,扫描一遍表,将入度为0的节点入栈?3.依次将栈中的节点出栈,每次出栈都将该节点的邻接点的入度减... 查看详情

缺少节点时 XSL 应用模板

】缺少节点时XSL应用模板【英文标题】:XSLapplytemplatewhennodeismissing【发布时间】:2014-03-1821:49:36【问题描述】:当我要格式化的节点丢失时,我无法应用模板。我不认为这种解释具有很强的描述性,因此我提供了一个模拟示例来... 查看详情

需要借助 xsl / xslt 将重复的 XML 节点放在单独的节点中

】需要借助xsl/xslt将重复的XML节点放在单独的节点中【英文标题】:needtoputrepeatingXMLnodesinseparatenodeswiththehelpofxsl/xslt【发布时间】:2019-09-0621:15:33【问题描述】:我有这个xml:<products><product><name>ad</name><category&... 查看详情