我想使用xslt“扫描”我的xml文件,并获取不同元素名称列表以及其属性名称。
我的XML:
<?xml version="1.0" encoding="UTF-8"?>
<dictionary>
<entry>
<form type="hyperlemma" xml:lang="cu">
<note type="editor's comment">CHECK</note>
<orth>hlE1</orth>
</form>
<form type="lemma" xml:lang="cu">
<orth>lE1</orth>
</form>
<form type="variant" xml:lang="cu">
<orth>var5</orth>
</form>
</entry>
<entry>
<form type="hyperlemma" xml:lang="cu">
<orth>hlE2</orth>
</form>
<form type="lemma" xml:lang="cu">
<orth>lE2</orth>
</form>
</entry>
</dictionary>
How to list complete XML document using XSLT中记录了获取不同元素名称列表的方法(请参阅Dimitre Novatchev的回答)。
使用此样式表
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output method="text"/>
<xsl:strip-space elements="*" />
<xsl:key name="kElemByName" match="*" use="name(.)"/>
<xsl:template match="
*[generate-id()
=
generate-id(key('kElemByName', name(.))[1])
]">
<xsl:value-of select="concat(name(.), '
')"/>
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
(正确)输出
dictionary
entry
form
note
orth
是否也可以获取属性名称?我想有以下输出
dictionary
entry
form type="hyperlemma" xml:lang="cu"
form type="lemma" xml:lang="cu"
form type="variant" xml:lang="cu"
note type="editor's comment"
orth
我如何实现这一目标?
答案 0 :(得分:1)
当您使用XSLT 2.0时,我只需使用for-each-group
解析它,并根据名称和属性计算分组键:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output method="text"/>
<xsl:strip-space elements="*" />
<xsl:template match="/">
<xsl:for-each-group select="//*" group-by="string-join((name(), @*/concat(name(), '="', ., '"')), ' ')">
<xsl:value-of select="concat(current-grouping-key(), ' ')"/>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
输出
dictionary
entry
form type="hyperlemma" xml:lang="cu"
note type="editor's comment"
orth
form type="lemma" xml:lang="cu"
form type="variant" xml:lang="cu"
撒克逊9.5对我来说。
如果要对输出进行排序,可以使用
<xsl:template match="/">
<xsl:for-each-group select="//*" group-by="string-join((name(), @*/concat(name(), '="', ., '"')), ' ')">
<xsl:sort select="current-grouping-key()"/>
<xsl:value-of select="concat(current-grouping-key(), ' ')"/>
</xsl:for-each-group>
</xsl:template>
我得到的方式
dictionary
entry
form type="hyperlemma" xml:lang="cu"
form type="lemma" xml:lang="cu"
form type="variant" xml:lang="cu"
note type="editor's comment"
orth
我认为要获得一致的结果,代码首先还需要按名称对属性进行排序,因为我怀疑输入是否为<foo att1="value1" att2="value2"/>
和<foo att2="value2" att1="value1"/>
,您只需要一个元素输出
可以使用
执行排序<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf"
version="2.0">
<xsl:output method="text"/>
<xsl:strip-space elements="*" />
<xsl:function name="mf:sort" as="attribute()*">
<xsl:param name="attributes" as="attribute()*"/>
<xsl:perform-sort select="$attributes">
<xsl:sort select="name()"/>
</xsl:perform-sort>
</xsl:function>
<xsl:template match="/">
<xsl:for-each-group select="//*" group-by="string-join((name(), mf:sort(@*)/concat(name(), '="', ., '"')), ' ')">
<xsl:sort select="current-grouping-key()"/>
<xsl:value-of select="concat(current-grouping-key(), ' ')"/>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
更简单的是使用distinct-values()
:
<xsl:template match="/">
<xsl:value-of select="distinct-values(//*/string-join(
(name(), @*/concat(name(), '="', ., '"')), ' '))"
separator=" "/>
</xsl:template>