我有一个示例xml文件,其中root的元素名为“element”。 这些元素可以嵌套。
我想排除名称为“position”的元素 “position”值x =(“number”+“another”)* count大于 所有“位置”元素的总和((“数字”+“另一个”)*“计数”)的平均值。
如何使用xslt v 1处理此xml文件。
<?xml version="1.0" encoding="utf-8" ?>
<root>
<element>
<position>
<number>
1
</number>
<another>
2
</another>
<count>
3
</count>
</position>
<position>
<number>
3
</number>
<another>
1
</another>
<count>
5
</count>
</position>
<element>
<position>
<number>
3
</number>
<another>
3
</another>
<count>
5
</count>
</position>
<position>
<number>
3
</number>
<another>
6
</another>
<count>
5
</count>
</position>
<element>
<position>
<number>
3
</number>
<another>
3
</another>
<count>
5
</count>
</position>
<position>
<number>
3
</number>
<another>
7
</another>
<count>
5
</count>
</position>
<element>
<position>
<number>
33
</number>
<another>
4
</another>
<count>
5
</count>
</position>
<position>
<number>
34
</number>
<another>
3
</another>
<count>
5
</count>
</position>
</element>
</element>
</element>
</element>
<element>
<position>
<number>
5
</number>
<another>
1
</another>
<count>
2
</count>
</position>
<position>
<number>
3
</number>
<another>
3
</another>
<count>
9
</count>
</position>
<element>
<position>
<number>
5
</number>
<another>
3
</another>
<count>
2
</count>
</position>
<position>
<number>
3
</number>
<another>
3
</another>
<count>
5
</count>
</position>
</element>
</element>
</root>
答案 0 :(得分:2)
我会使用以下两遍方法:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common" exclude-result-prefixes="ext">
<xsl:output omit-xml-declaration="yes"/>
<xsl:variable name="vrtfPass1">
<xsl:apply-templates select="/*" mode="getScore"/>
</xsl:variable>
<xsl:variable name="vPass1" select="ext:node-set($vrtfPass1)/*"/>
<xsl:variable name="vAverage" select=
"sum($vPass1//position/@score) div count($vPass1//position)"/>
<xsl:template match="node()|@*" name="identity" mode="getScore">
<xsl:copy>
<xsl:apply-templates select="node()|@*" mode="getScore"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="$vPass1"/>
</xsl:template>
<xsl:template match="position" mode="getScore">
<position score="{(number + another)*count}">
<xsl:apply-templates mode="getScore"/>
</position>
</xsl:template>
<xsl:template match="position">
<xsl:if test="not(@score > $vAverage)">
<position>
<xsl:apply-templates mode="getScore"/>
</position>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档:
<root>
<element>
<position>
<number>1</number>
<another>2</another>
<count>3</count>
</position>
<position>
<number>3</number>
<another>1</another>
<count>5</count>
</position>
<element>
<position>
<number>3</number>
<another>3</another>
<count>5</count>
</position>
<position>
<number>3</number>
<another>6</another>
<count>5</count>
</position>
<element>
<position>
<number>3</number>
<another>3</another>
<count>5</count>
</position>
<position>
<number>3</number>
<another>7</another>
<count>5</count>
</position>
<element>
<position>
<number>33</number>
<another>4</another>
<count>5</count>
</position>
<position>
<number>34</number>
<another>3</another>
<count>5</count>
</position>
</element>
</element>
</element>
</element>
<element>
<position>
<number>5</number>
<another>1</another>
<count>2</count>
</position>
<position>
<number>3</number>
<another>3</another>
<count>9</count>
</position>
<element>
<position>
<number>5</number>
<another>3</another>
<count>2</count>
</position>
<position>
<number>3</number>
<another>3</another>
<count>5</count>
</position>
</element>
</element>
</root>
产生了想要的正确结果:
<root>
<element>
<position>
<number>1</number>
<another>2</another>
<count>3</count>
</position>
<position>
<number>3</number>
<another>1</another>
<count>5</count>
</position>
<element>
<position>
<number>3</number>
<another>3</another>
<count>5</count>
</position>
<position>
<number>3</number>
<another>6</another>
<count>5</count>
</position>
<element>
<position>
<number>3</number>
<another>3</another>
<count>5</count>
</position>
<position>
<number>3</number>
<another>7</another>
<count>5</count>
</position>
<element>
</element>
</element>
</element>
</element>
<element>
<position>
<number>5</number>
<another>1</another>
<count>2</count>
</position>
<position>
<number>3</number>
<another>3</another>
<count>9</count>
</position>
<element>
<position>
<number>5</number>
<another>3</another>
<count>2</count>
</position>
<position>
<number>3</number>
<another>3</another>
<count>5</count>
</position>
</element>
</element>
</root>
答案 1 :(得分:0)
只是为了好玩,这个样式表没有扩展名:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="vAvgPosition">
<xsl:apply-templates select="/descendant::position[1]"
mode="avgPosition"/>
</xsl:variable>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="position" mode="avgPosition">
<xsl:param name="pSum" select="0"/>
<xsl:param name="pCount" select="0"/>
<xsl:variable name="vSum"
select="$pSum + (number + another) * count"/>
<xsl:variable name="vCount" select="$pCount + 1"/>
<xsl:variable name="vNext" select="following::position[1]"/>
<xsl:apply-templates select="$vNext" mode="avgPosition">
<xsl:with-param name="pSum" select="$vSum"/>
<xsl:with-param name="pCount" select="$vCount"/>
</xsl:apply-templates>
<xsl:if test="not($vNext)">
<xsl:value-of select="$vSum div $vCount"/>
</xsl:if>
</xsl:template>
<xsl:template match="position">
<xsl:if test="not((number + another) * count > $vAvgPosition)">
<xsl:call-template name="identity"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
输出:
<root>
<element>
<position>
<number>1</number>
<another>2</another>
<count>3</count>
</position>
<position>
<number>3</number>
<another>1</another>
<count>5</count>
</position>
<element>
<position>
<number>3</number>
<another>3</another>
<count>5</count>
</position>
<position>
<number>3</number>
<another>6</another>
<count>5</count>
</position>
<element>
<position>
<number>3</number>
<another>3</another>
<count>5</count>
</position>
<position>
<number>3</number>
<another>7</another>
<count>5</count>
</position>
<element></element>
</element>
</element>
</element>
<element>
<position>
<number>5</number>
<another>1</another>
<count>2</count>
</position>
<position>
<number>3</number>
<another>3</another>
<count>9</count>
</position>
<element>
<position>
<number>5</number>
<another>3</another>
<count>2</count>
</position>
<position>
<number>3</number>
<another>3</another>
<count>5</count>
</position>
</element>
</element>
</root>
了解XSLT 2.0解决方案的紧凑程度:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:variable name="vAvgPosition"
select="avg(//position/((number+another)*count))"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="position[(number+another)*count > $vAvgPosition]"/>
</xsl:stylesheet>