是否有可能检查xml文件中是否存在重复节点,然后检查此节点的包含,如果可能,使用xslt将这两个节点与Id编号区分开来? 我有例如这个xml文件
<Racine>
<el1>
<fils1>context1</fils1>
<fils2>test1</fils2>
<fils1>context1</fils1>
</el1>
<el2>
<fils1>context2</fils1>
<fils2>test2</fils2>
<fils1>context2</fils1>
</el2>
<el3>...........<el3>
</Racine>
在这种情况下,例如,节点“ fils1 ”在节点“ el1 ”中出现两次,并且每个节点的包含相同。在这种情况下,我需要转换我的xml文件,以便此节点变为
<fils1 id=1>context1</fils1>.
我自动添加一个Id-number来区分具有相同名称和相同名称的两个节点。当节点使用不同的包含相同的名称时(也必须将节点包含中的空格视为差异),然后让节点保持原样。
如何使用XSLT实现这一目标?有人可以帮我改变吗?
非常感谢你的帮助。
永邦
感谢你的评论。这是预期的输出:
<Racine>
<el1>
<fils1 id=1>context1</fils1>
<fils2>test1</fils2>
<fils1 id=2>context1</fils1>
</el1>
<el2>
<fils1 id=1>context2</fils1>
<fils2>test2</fils2>
<fils1 id=2>context2</fils1>
</el2>
<el3>...........
<fils1 id=3>context1</fils1>
<el3>
</Racine>
在“ el1 ”和“ el2 ”中记录节点“ fils2 ”,包含是不同的,那么我想保留它们unchange,如果没有,我想添加一个id号来区别。
答案 0 :(得分:0)
这个XSLT 1.0样式表...
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />
<xsl:key name="kCommon" match="*[starts-with(name(),'fils')]"
use="concat(name(),'|',.)" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[starts-with(name(),'fils')]
[count(key('kCommon',concat(name(),'|',.))) >= 2]">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:variable name="this-key" select="concat(name(),'|',.)" />
<xsl:attribute name="id"><xsl:value-of select="
count(preceding::*
[starts-with(name(),'fils')]
[count(.|key('kCommon',$this-key)) =
count( key('kCommon',$this-key)) ]
) + 1" /></xsl:attribute>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
...将改变这一输入...
<Racine>
<el1>
<fils1>context1</fils1>
<fils2>test1</fils2>
<fils1>context1</fils1>
</el1>
<el2>
<fils1>context2</fils1>
<fils2>test2</fils2>
<fils1>context2</fils1>
</el2>
<el3>
<fils1>context1</fils1>
</el3>
</Racine>
... INTO ...
<Racine>
<el1>
<fils1 id="1">context1</fils1>
<fils2>test1</fils2>
<fils1 id="2">context1</fils1>
</el1>
<el2>
<fils1 id="1">context2</fils1>
<fils2>test2</fils2>
<fils1 id="2">context2</fils1>
</el2>
<el3>
<fils1 id="3">context1</fils1>
</el3>
</Racine>
我们构建了一个具有通用名称和通用文本内容的fils元素的键('kCommon')。我们寻找具有至少两个密钥组成员资格的元素 - 换句话说,具有与至少一个其他filX元素共同的名称和文本的filX类型元素。这是我们的最后一个模板。
对于每个这样的共同元素,我们构建两个集合:
公共组中所有前面的fil元素的集合。这个集合由......提供。
preceding::*[starts-with(name(),'fils')]
此节点的通用名称+内容组,即......
key('kCommon',concat(name(),'|',.))
但是因为我们将引用concat(name(),'|',.)静音几次,并且在我们无法直接访问此上下文节点的地方,我们只计算concat()和替换像这样进入Set 2。现在可以快速计算第2组。
key('kCommon',$this-key)
然后我们使用Kaysian method进行集合交集。
$set1[count(.|$set2)=count($set2)]
这个交集是在它之前的所有相似元素的集合。我们只计算它们并添加一个,这给了我们id属性的序数。