代码之家  ›  专栏  ›  技术社区  ›  mikelikespie

管理XML中的ID和对ID的引用

  •  0
  • mikelikespie  · 技术社区  · 15 年前

    我试图将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来完成它,但我希望有一种更简单的方法。

    谢谢!

    2 回复  |  直到 15 年前
        1
  •  0
  •   Jukka Matilainen    15 年前

    如果您最终使用了XSLT,则可以找到 generate-id 用于生成ID的函数。

    下面是一个使用XSLT1.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>
    

    如果你不喜欢由 生成ID (或者,如果您由于其他原因不能使用它——为了确保获得唯一的ID,需要在同一转换中处理所有节点),您可以用其他逻辑替换对它的调用,例如添加后缀。

        2
  •  0
  •   Tom Rudick    15 年前

    不是很好的解决方案,但您可以始终使用一些正则表达式。

    匹配 id=(.*) 然后用你想要的东西替换所有的1美元。