在XML中管理ID和ID的引用

时间:2009-11-12 22:35:11

标签: xml xslt svg

我正在尝试将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 个答案:

答案 0 :(得分:0)

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

id=(.*)上匹配,然后将所有#$ 1替换为您想要的任何内容。

答案 1 :(得分:0)

如果您最终使用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,则需要在同一转换中处理所有节点)可以用其他逻辑替换对它的调用,比如添加后缀。