我正在尝试将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来做,但希望有一种更简单的方法。
谢谢!
答案 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,则需要在同一转换中处理所有节点)可以用其他逻辑替换对它的调用,比如添加后缀。