嵌套元素的XML使用XSLT v1.0 C#进行计算过滤#

时间:2011-01-27 20:31:24

标签: xml xslt xslt-1.0 xslcompiledtransform

我有一个示例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>

2 个答案:

答案 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>