You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何比对XML所有way节点首尾nd的ref属性并返回仅出现一次的值

XSLT筛选唯一端点节点解决方案

需求说明

比对所有<way>节点下第一个和最后一个<nd>节点的ref属性,仅返回ref值在所有首尾节点中唯一出现的<nd>节点。

现有XML结构

<osm>
  <way>
    <nd ref="1"/>
    <nd ref="2"/>
    <nd ref="3"/>
    <tag k="highway"/>
  </way>
  <way>
    <nd ref="2"/>
    <nd ref="3"/>
    <nd ref="4"/>
    <tag k="highway"/>
  </way>
  <way>
    <nd ref="4"/>
    <nd ref="6"/>
    <nd ref="1"/>
    <tag k="highway"/>
  </way>
  <way>
    <nd ref="2"/>
    <nd ref="4"/>
    <nd ref="7"/>
    <tag k="highway"/>
  </way>
</osm>

预期输出

<nd ref="3"/>
<nd ref="7"/>

正确实现代码(XSLT 2.0)

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
    <xsl:template match="/">
        <!-- 收集所有way的首尾nd节点 -->
        <xsl:variable name="allEndNodes" select="osm/way/*[self::nd and (position()=1 or position()=last())]"/>
        <!-- 按ref分组,筛选仅出现1次的节点 -->
        <xsl:for-each-group select="$allEndNodes" group-by="@ref">
            <xsl:if test="count(current-group()) = 1">
                <xsl:copy-of select="."/>
            </xsl:if>
        </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>

逻辑说明

  1. 先通过$allEndNodes变量收集所有<way>下的第一个和最后一个<nd>节点,排除中间的<nd>和<tag>节点
  2. 用XSLT 2.0的分组特性按ref属性对所有端点节点分组
  3. 筛选分组大小为1的节点,即ref值唯一的节点,直接拷贝输出即可

内容的提问来源于stack exchange,提问作者DaveF

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 13:24:02