我正在编写一个XPath表达式来计算独特的子代理。使用以下xPath表达式,我可以获取所有子属性以及不唯一的属性:
//*[count(*)=0]
我需要一个XPath表达式来返回所有唯一属性和唯一属性数量
例如:XML文件
<details>
<Employee>
<EmpNo>10</EmpNo>
<EmpName>TestName</EmpName>
<Address>
<Address1>market</Address1>
<Address2>motel</Address2>
<Street/>
</Address>
</Employee>
<Employee>
<EmpNo>20</EmpNo>
<EmpName>TestName2</EmpName>
<Address>
<Address1>school</Address1>
<Address2>playground</Address2>
<Street>
<StreetName>TestStreet2</StreetName>
<StreetCode>200</StreetCode>
</Street>
</Address>
</Employee>
预期产出:
<!-- Unique element's count -->
<data>6</data>
<!-- Unique Element Names -->
<data>EmpNo</data>
<data>EmpName</data>
<data>Address1</data>
<data>Address2</data>
<data>StreetName</data>
<data>StreetCode</data>
<!-- Unique Element values -->
<!-- Data Set 1 -->
<data>10</data>
<data>TestName</data>
<data>market</data>
<data>motel</data>
<data>null</data>
<data>null</data>
<!-- Data Set 2 -->
<data>20</data>
<data>TestName2</data>
<data>school</data>
<data>playground</data>
<data>TestStreet2</data>
<data>200</data>
感谢。
答案 0 :(得分:1)
此XSLT 1.0样式表
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output indent="yes" omit-xml-declaration="yes" />
<!-- index data fields by their element name -->
<xsl:key
name = "kFields"
match = "Employee//*"
use = "name()"
/>
<!-- store a unique list of elements (Muenchian Grouping) -->
<xsl:variable name="fields" select="
/details/Employee//*[
generate-id()
=
generate-id(key('kFields', name())[1])
][
not(
key('kFields', name())/*
)
]
" />
<!-- main output ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<xsl:template match="/details">
<xsl:comment> unique element count </xsl:comment>
<data>
<xsl:value-of select="count($fields)" />
</data>
<xsl:call-template name="newline" />
<xsl:comment> unique element names </xsl:comment>
<xsl:for-each select="$fields">
<data>
<xsl:value-of select="name()" />
</data>
<xsl:call-template name="newline" />
</xsl:for-each>
<xsl:comment> unique element values </xsl:comment>
<xsl:apply-templates select="Employee" />
</xsl:template>
<!-- Employee output ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<xsl:template match="Employee">
<xsl:variable name="this" select="." />
<xsl:comment> data set <xsl:value-of select="position()" /> </xsl:comment>
<xsl:for-each select="$fields">
<xsl:variable
name="val"
select="$this//*[not(*) and name() = name(current())]"
/>
<data>
<xsl:choose>
<xsl:when test="normalize-space($val) != ''">
<xsl:value-of select="$val" />
</xsl:when>
<xsl:otherwise>
<xsl:text>null</xsl:text>
</xsl:otherwise>
</xsl:choose>
</data>
<xsl:call-template name="newline" />
</xsl:for-each>
</xsl:template>
<!-- Helpers ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<xsl:template name="newline">
<xsl:value-of select="'
'" />
</xsl:template>
</xsl:stylesheet>
生成(换行符可能会以不同方式重现):
<!-- unique element count -->
<data>6</data>
<!-- unique element names -->
<data>EmpNo</data>
<data>EmpName</data>
<data>Address1</data>
<data>Address2</data>
<data>StreetName</data>
<data>StreetCode</data>
<!-- unique element values -->
<!-- data set 1 -->
<data>10</data>
<data>TestName</data>
<data>market</data>
<data>motel</data>
<data>null</data>
<data>null</data>
<!-- data set 2 -->
<data>20</data>
<data>TestName2</data>
<data>school</data>
<data>playground</data>
<data>TestStreet2</data>
<data>200</data>
注意:
//*[count(*)=0]
和//*[not(*)]
相同。后者更好。<xsl:key>
和 Muenchian分组来计算<Employee>
$fields
中的XPath表达式做了两件事:
name()
成为唯一元素。not( key('kFields', name())/* )
。否则<data>Street</data>
会显示在输出中。