我有一些不友好和半生不熟的xml文件,类似于以下内容:
<root>
<child0><name0>Bob Dylan</name0></child0>
<child1><name1>Daft Punk</name1></child1>
<child2><name2>Nine Inch Nails</name2></child2>
</root>
我希望将每个文件转换为以下内容:
<root><children>
<child><name>Bob Dylan</name></child>
<child><name>Daft Punk</name></child>
<child><name>Nine Inch Nails</name></child>
</children>
</root>
每个文件都没有确定数量的子项。有些人只有<child0>
而有些人有<child0> ... <child10>
。儿童中的元素也未确定,例如。 name [0]等。
所以我想遍历每个孩子(可能带有通配符或者结尾,或者??)以匹配始终终止子和孩子的子元素的数字。
这不起作用,但有些东西:
<xsl:for-each select="child*" >
<child>
<name><xsl:value-of select="name[index]"></name>
</child>
</xsl:for-each>
我已经看到很多关于select,if和match条件的例子,这些条件涉及选择元素内的内容(或通过位置或索引选择元素)... 因为那应该是这样做的。
但我有一半有效的xml。
答案 0 :(得分:2)
这是一个直接的,面向推送的解决方案,可以实现您的需求。请注意,它可以使用XSLT / XPath 1.0或2.0。
当这个XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:strip-space elements="*" />
<xsl:template match="/*">
<root>
<children>
<xsl:apply-templates />
</children>
</root>
</xsl:template>
<xsl:template match="*[starts-with(name(), 'child')]">
<child>
<xsl:apply-templates />
</child>
</xsl:template>
<xsl:template match="*[starts-with(name(), 'name')]">
<name>
<xsl:apply-templates />
</name>
</xsl:template>
</xsl:stylesheet>
...适用于原始XML:
<root>
<child0>
<name0>Bob Dylan</name0>
</child0>
<child1>
<name1>Daft Punk</name1>
</child1>
<child2>
<name2>Nine Inch Nails</name2>
</child2>
</root>
...生成了想要的结果:
<root>
<children>
<child>
<name>Bob Dylan</name>
</child>
<child>
<name>Daft Punk</name>
</child>
<child>
<name>Nine Inch Nails</name>
</child>
</children>
</root>
答案 1 :(得分:0)
一种简单的方法是在name()值上使用正则表达式:
<xsl:for-each select="*[matches(name(),'^child\d$')]">
...