【问题标题】:Mangling IDs and References to IDs in XML在 XML 中修改 ID 和对 ID 的引用
【发布时间】:2010-12-16 02:27:32
【问题描述】:

我正在尝试将 xml 元素组合在一起,而我遇到的问题是当有相同的 ID 时。基本上我需要做的是修改 xml 文件中的所有 ID,以及对它们的引用。 (我正在使用 SVG 来添加一些上下文)

说我有:

<bar id="foo"/>
<baz ref="url(#foo)"/>
<bar id="abc"/>
<baz ref="asdf:url(#abc)"/>

我想要一种方法来自动将其转换为:

<bar id="foo_1"/>
<baz ref="url(#foo_1)"/>
<bar id="abc_1"/>
<baz ref="asdf:url(#abc_1)"/>

或类似的东西。

我可能可以编写一些 XSL 来实现它,但希望有更简单的方法。

谢谢!

【问题讨论】:

    标签: xml xslt svg


    【解决方案1】:

    如果您最终使用 XSLT,您可能会发现 generate-id 函数对生成 id 很有用。

    这是一个使用 XSLT 1.0 的虚拟示例:

    <xsl:stylesheet version="1.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
      <xsl:key name="element-by-id" match="//*" use="@id"/>
    
      <!-- identity transform: everything as-is... -->
      <xsl:template match="@*|node()">
        <xsl:copy>
          <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
      </xsl:template>
    
      <!-- ... except for rewritten id's -->
      <xsl:template match="@id">
        <xsl:attribute name="id">
          <xsl:value-of select="generate-id(..)"/>
        </xsl:attribute>
      </xsl:template>
    
      <!-- ... and rewritten id references -->
      <xsl:template match="@ref">
        <xsl:variable name="head" select="substring-before(., 'url(#')"/>
        <xsl:variable name="tail" select="substring-after(., 'url(#')"/>
        <xsl:variable name="idref" select="substring-before($tail, ')')"/>
        <xsl:variable name="end" select="substring-after($tail, ')')"/>
        <xsl:attribute name="ref">
          <xsl:value-of select="concat($head, 'url(#', 
                                generate-id(key('element-by-id', $idref)), 
                                ')', $end)"/>
        </xsl:attribute>
      </xsl:template>
    
    </xsl:stylesheet>
    

    如果您不喜欢 generate-id 生成的 id(或者如果您因其他原因无法使用它 - 以确保您获得唯一的 id 需要在同一转换中处理的所有节点),您可以替换使用其他逻辑调用它,例如添加后缀。

    【讨论】:

      【解决方案2】:

      不是一个非常优雅的解决方案,但您总是可以使用一些正则表达式。

      匹配id=(.*),然后用你想要的任何东西替换所有#$1。

      【讨论】:

      • 是的,我正在考虑。 sed 是一切的解决方案:)。由于我们只对我们制作的 SVG 进行此操作,我想我们不必担心像 这样的 xml 或类似的奇怪东西。我更喜欢更“正确”的解决方案,但这绝对适用于大多数常见情况。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-07
      • 1970-01-01
      • 2015-06-10
      • 1970-01-01
      • 1970-01-01
      • 2014-02-03
      • 1970-01-01
      相关资源
      最近更新 更多