2

XSLT では、テンプレートを呼び出して、コンテンツをテンプレートに渡したいと思います。ただし、コンテンツは、コンテンツが並べ替えられた順序 (61-41-13) ではなく、ビデオが並べ替えられた方法 (13-41-61) で並べ替える必要があります。

次の XML があります。

<videos>
    <video key="13" />
    <video key="41" />
    <video key="61" />
</videos>


<contents>
    <content key="61" />
    <content key="41" />
    <content key="13" />
    <content key="10" />
</contents>

XSLT:

<xsl:call-template name="video">
    <xsl:with-param name="content" select="contents/content[@key = videos/video/@key]" />
</xsl:call-template>

これを簡単に達成する方法はありますか?

4

3 に答える 3

1

This transformation seems to be the most efficient of the currently posted solutions -- no count(preceding-sibling::*), and no //content[@key=$key] -- both of which result in O(N^2) -- quadratical time complexity:

<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="kContByAtttr" match="content" use="@key"/>
 <xsl:key name="kVidByAtttr" match="video" use="@key"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="contents">
  <contents>
   <xsl:for-each select="/*/videos/video">
     <xsl:apply-templates select="key('kContByAtttr', @key)"/>
   </xsl:for-each>
   <xsl:apply-templates select="*[not(key('kVidByAtttr', @key))]"/>
  </contents>
 </xsl:template>
</xsl:stylesheet>

When applied on the provided XML (wrapped into a single top element to become a) document:

<t>
    <videos>
        <video key="13" />
        <video key="41" />
        <video key="61" />
    </videos>
    <contents>
        <content key="61" />
        <content key="41" />
        <content key="13" />
        <content key="10" />
    </contents>
</t>

produces the wanted, correct result:

<t>
   <videos>
      <video key="13"/>
      <video key="41"/>
      <video key="61"/>
   </videos>
   <contents>
      <content key="13"/>
      <content key="41"/>
      <content key="61"/>
      <content key="10"/>
   </contents>
</t>
于 2013-04-12T14:49:12.377 に答える
0

私が通常使用するコードのスニペットをコピーして貼り付けると、うまくいくはずです

<xsl:template match="/">
  <contents>
    <xsl:for-each select="//video">
      <xsl:call-template name="sortedId">
        <xsl:with-param name="key" select="@key"></xsl:with-param>
      </xsl:call-template>
    </xsl:for-each>
  </contents>    
</xsl:template>


<xsl:template name="sortedId" >
    <xsl:param name="key"></xsl:param>
    <xsl:apply-templates select="//content[@key=$key]" />
</xsl:template>

<xsl:template match="content">
    <xsl:copy-of select="." />
</xsl:template>

結果は次のとおりです。

<contents>
  <content key="13" />
  <content key="41" />
  <content key="61" />
</contents>
于 2013-04-12T10:38:50.610 に答える
0

を使用する必要がある特定の理由はあります<xsl:call-template>か? <content>要素が存在する順序で要素を並べ替えたい場合は、次の<video>ようにすることができます。

スタイルシート

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"
    omit-xml-declaration="yes"/>
  <xsl:strip-space elements="*"/>

  <!--
  Index <video> elements according to their position in the tree.
  See http://stackoverflow.com/a/5876074/825783
  -->
  <xsl:key name="kVideo" match="video"
    use="count(preceding-sibling::video) + 1"/>

  <!-- Identity transform -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="content">
    <xsl:copy>
      <!--
      Apply attributes (fallback to account for the extra <content> element)
      -->
      <xsl:apply-templates select="@*"/>
      <!--
      Apply the @key attribute of the <video> element that's in a
      position corresponding to the position of this <content> element
      -->
      <xsl:apply-templates select="key('kVideo', position())/@key"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

入力

<root>
  <videos>
    <video key="13"/>
    <video key="41"/>
    <video key="61"/>
  </videos>
  <contents>
    <content key="61"/>
    <content key="41"/>
    <content key="13"/>
    <content key="10"/>
  </contents>
</root>

出力

<root>
  <videos>
    <video key="13"/>
    <video key="41"/>
    <video key="61"/>
  </videos>
  <contents>
    <content key="13"/>
    <content key="41"/>
    <content key="61"/>
    <content key="10"/>
  </contents>
</root>
于 2013-04-12T11:37:22.660 に答える