3

以下のXMLを使用しています

<Root>
<sample>1</sample>
<sample>2</sample>
<sample>3</sample>
<sample>4</sample>
<sample>5</sample>
<sample>6</sample>
</Root>

以下のように出力を取得したい

<sample>123456</sample>

上記の出力を取得するために、以下の XSLT を使用しています。しかし、私はこのような出力を得ています。

<sample>1</sample>
<sample>23456</sample>
<sample>2</sample>
<sample>3456</sample>
<sample>3</sample>
<sample>456</sample>
<sample>4</sample>
<sample>56</sample>
<sample>5</sample>
<sample>6</sample
><sample>6</sample>
<sample></sample>

これは私が試したXSLコードです:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="sample">
<presample>
<xsl:value-of select="."/>
<xsl:variable name="code" select="following-sibling::sample" />
<xsl:for-each select="following-sibling::sample">
<xsl:if test="not(preceding-sibling::sample)">
<xsl:value-of select="."/>
</xsl:if>
</xsl:for-each>
</presample>
</xsl:template>
</xsl:stylesheet>

上記の目的の出力を得るために、この XSLT を修正するのを手伝ってください。

4

3 に答える 3

2

これはどうですか:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="sample[1]">
    <sample>
      <xsl:for-each select=". | following-sibling::sample">
        <xsl:value-of select="."/>
      </xsl:for-each>
    </sample>
  </xsl:template>

  <xsl:template match="sample[position() > 1]" />
</xsl:stylesheet>

あなたの最終的な目標はこれよりも少し複雑だと思うので、それについて詳しく説明できれば、より良い一般的なアプローチがあるかもしれません.

これが目的であるかどうかはわかりませんが、より一般的なアプローチの可能性があります。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="*[text()[normalize-space(.)] and not(name(preceding-sibling::*[1]) = name())]">
    <xsl:copy>
      <xsl:variable name="list" select=". | following-sibling::*"/>
      <xsl:for-each select="$list">
        <xsl:variable name="pos" select="position()" />
        <xsl:if test="not($list[position() &lt; $pos and name() != name(current())])">
          <xsl:value-of select="."/>
        </xsl:if>
      </xsl:for-each>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="*[name(preceding-sibling::*[1]) = name()]" />
  <xsl:template match="text()" />
</xsl:stylesheet>

これで実行すると:

<Root>
  <sample>1</sample>
  <sample>2</sample>
  <sample>3</sample>
  <sample>4</sample>
  <sample>5</sample>
  <sample>6</sample>
  <child>
    <something>4</something>
    <something>5</something>
    <something>6</something>
    <something>7</something>
    <somethingelse>a</somethingelse>
    <somethingelse>b</somethingelse>
    <somethingelse>c</somethingelse>
    <somethingelse>d</somethingelse>
    <something>8</something>
    <something>9</something>
    <something>10</something>
  </child>
</Root>

これを生成します:

<sample>123456</sample>
<something>4567</something>
<somethingelse>abcd</somethingelse>
<something>8910</something>
于 2013-01-11T06:38:58.807 に答える
0
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="sample[not(preceding-sibling::sample)]">
    <sample>
      <xsl:for-each select=". | following-sibling::sample">
        <xsl:value-of select="."/>
      </xsl:for-each>
    </sample>
  </xsl:template>

  <xsl:template match="sample[preceding-sibling::sample]" />
</xsl:stylesheet>

入力XMLの場合:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <sample>1</sample>
  <sample>2</sample>
  <sample>3</sample>
  <sample>4</sample>
  <dummy1>a</dummy1>
  <dummy2>b</dummy2>
  <dummy3>c</dummy3>
  <dummy4>d</dummy4>
  <sample>5</sample>
  <sample>6</sample>
  <sample>7</sample>
  <sample>8</sample>
</root>

そして、出力は次のようになります。

<?xml version="1.0" encoding="utf-8"?>
<root>
  <sample>12345678</sample>
  <dummy1>a</dummy1>
  <dummy2>b</dummy2>
  <dummy3>c</dummy3>
  <dummy4>d</dummy4>
</root>
于 2013-01-11T08:46:10.950 に答える
0

これは、兄弟軸を使用するよりもはるかに効率的なグループ化方法である Muenchian グループ化方法の単純なアプリケーションです

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>
 <xsl:key name="kSampleByVal" match="sample" use="."/>

 <xsl:template match="sample[1]" priority="2">
  <sample>
   <xsl:apply-templates select=
   "../*[generate-id()=generate-id(key('kSampleByVal',.)[1])]/text()"/>
  </sample>
 </xsl:template>
 <xsl:template match="*/*"/>
</xsl:stylesheet>

この変換が次の XML ドキュメントに適用された場合(提供されたものは、より代表的なものになるように変更されています):

<Root>
    <sample>1</sample>
    <sample>2</sample>
    <sample>3</sample>
    <sample>4</sample>
    <sample>5</sample>
    <sample>6</sample>
    <sample>3</sample>
    <sample>4</sample>
    <sample>1</sample>
    <sample>2</sample>
    <sample>3</sample>
</Root>

必要な正しい結果が生成されます。

<sample>123456</sample>   

注意してください:

すべての場合において、兄弟比較グループ化よりも Muenchian グループ化法を使用することをお勧めします。Muenchian の時間計算量は O(N) ですが、兄弟比較グループの時間計算量は 2 次 (O(N^2)) です。兄弟比較のグループ化には 40 分かかりましたが、Muenchian のグループ化にはわずか 2 秒しかかかりませんでした。

于 2013-01-11T13:23:12.640 に答える