2011-01-27 15 views
0

ルートに "要素"という名前の要素があるサンプルXMLファイルがあります。 この要素はネストできます。XSLT v1.0を使用したネストされた要素のXMLによるフィルタリングC#

"位置"値x =( "number" + "another")* countが より大きい要素を除外したいと考えています(( "number" + "another" )* "count")をすべての "position"要素から削除します。 XSLT vで、このXMLファイルを処理する方法

1.

<?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

私は、次の2つのパスのアプローチを使用します。提供されるXML文書に適用

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

<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> 
+0

私はXslCompiledTransformクラスを使用して追加することを忘れていますあなたのアプローチを適用することは可能ですか? – marcinn

+0

+1。とても素敵です。 – Flack

+0

http://www.tkachenko.com/blog/archives/000714.html Dimitreへの私のコメントへの付録 – marcinn

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>