2

映画のリストを表示する XML ファイルがあります。各映画には、プロット、俳優、監督などを説明するメタデータがあります。これは構造の例です。

<movies>
    <movie>
    <title>The Shawshank Redemption</title>
    <year>1994</year>
    <rated>R</rated>
    <released>1994 Oct 14</released>
    <runtime>142 min</runtime>
    <genres>
        <genre>Crime</genre>
        <genre>Drama</genre>
    </genres>
    <directors>
        <director>Name Surname</director>
    </directors>
    <writers>
        <writer>Stephen King (short story 'Rita Hayworth and Shawshank Redemption')</writer>
        <writer>Frank Darabont (screenplay)</writer>
    </writers>
    <actors>
        <actor>Tim Robbins</actor>
        <actor>Morgan Freeman</actor>
        <actor>Bob Gunton</actor>
        <actor>William Sadler</actor>
    </actors>
    <plot>Two imprisoned men bond over a number of years, finding solace and eventual redemption through acts of common decency.</plot>
    <languages>
        <language>English</language>
    </languages>
    <countries>
        <country>USA</country>
    </countries>
    <awards>Nominated for 7 Oscars. Another 16 wins and 16 nominations.</awards>
    <poster>http://ia.media-imdb.com/images/M/MV5BODU4MjU4NjIwNl5BMl5BanBnXkFtZTgwMDU2MjEyMDE@._V1_SX300.jpg</poster>
    <metascore>80</metascore>
    <imdbRating>9.3</imdbRating>
    <imdbVotes>1358212</imdbVotes>
    <imdbID>tt0111161</imdbID>
    <type>movie</type>
    </movie>
    <movie>
    ...
    </movie>
    <movie>
    ...
    </movie>
    ...
</movies>

XSL スタイルシートを作成して、このファイルを映画と俳優の関係を示すグラフファイルに変換する必要があります。ここで、ノードは映画であり、俳優が映画 (ノード) に接続されている場合、2 つのノード間のエッジが存在します。ここに例があります:

<key id="actors" for="edge" attr.name="actors" attr.type="int">
    <default>1</default>
</key>

<graph id="movies" edgedefault="undirected">

<node id="movie title 1"/>
<node id="movie title 2"/>
<node id="movie title 3"/>
...

<edge source="movie title 1" target="movie title 2">
    <data key="actors">2</data> (number of actors who appear in both "movie title 1" and "movie title 2")
</edge>

これは、ノードを一覧表示する XSL の一部です。

<xsl:for-each-group select="/movies/movie" group-by=".">
    <xsl:sort select="current-grouping-key()"/>         
    <node><xsl:attribute name="id"><xsl:value-of select="current-grouping-key()"/></xsl:attribute></node>
    <xsl:text>&#xa;</xsl:text>
</xsl:for-each-group>
<xsl:text>&#xa;</xsl:text>

回答ありがとうございます。

4

1 に答える 1

6

あなたの質問はあまり明確ではないと思います。同じ俳優の映画を接続するグラフが必要な場合は、(a) 複数の映画があり、(b) そのうちのいくつかに同じ俳優がいるという例から始める必要があります。

XML

<movies>
   <movie>
      <title>Alpha</title>
      <actors>
         <actor>Adam</actor>
         <actor>Betty</actor>
         <actor>Cecil</actor>
      </actors>
   </movie>
   <movie>
      <title>Bravo</title>
      <actors>
         <actor>Adam</actor>
         <actor>Betty</actor>
         <actor>David</actor>
      </actors>
   </movie>
   <movie>
      <title>Charlie</title>
      <actors>
         <actor>Adam</actor>
         <actor>David</actor>
         <actor>Eve</actor>
      </actors>
   </movie>
   <movie>
      <title>Delta</title>
      <actors>
         <actor>Cecil</actor>
         <actor>Eve</actor>
      </actors>
   </movie>
   <movie>
      <title>Echo</title>
      <actors>
         <actor>Frank</actor>
         <actor>George</actor>
      </actors>
   </movie>
</movies>

次に、次のスタイルシートを適用します。

XSLT1.0

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

<xsl:key name="movie-by-actor" match="movie" use="actors/actor" />

<xsl:template match="/movies">
    <graphml xmlns="http://graphml.graphdrawing.org/xmlns"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
        <key id="actors" for="edge" attr.name="actors" attr.type="int"/>
        <graph id="movies" edgedefault="undirected">
            <xsl:for-each select="movie">
                <xsl:variable name="source" select="." />
                <node id="{title}"/>
                    <xsl:for-each select="key('movie-by-actor', actors/actor)[not(title=$source/title)]">
                        <edge source="{$source/title}" target="{title}">
                            <data key="actors">
                                <xsl:value-of select="count(actors/actor[.=$source/actors/actor])"/>
                            </data>
                        </edge>
                    </xsl:for-each>
            </xsl:for-each>
        </graph>
    </graphml>
</xsl:template>

</xsl:stylesheet>

次の結果が生成されます。

<?xml version="1.0" encoding="UTF-8"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
   <key id="actors" for="edge" attr.name="actors" attr.type="int"/>
   <graph id="movies" edgedefault="undirected">
      <node id="Alpha"/>
      <edge source="Alpha" target="Bravo">
         <data key="actors">2</data>
      </edge>
      <edge source="Alpha" target="Charlie">
         <data key="actors">1</data>
      </edge>
      <edge source="Alpha" target="Delta">
         <data key="actors">1</data>
      </edge>
      <node id="Bravo"/>
      <edge source="Bravo" target="Alpha">
         <data key="actors">2</data>
      </edge>
      <edge source="Bravo" target="Charlie">
         <data key="actors">2</data>
      </edge>
      <node id="Charlie"/>
      <edge source="Charlie" target="Alpha">
         <data key="actors">1</data>
      </edge>
      <edge source="Charlie" target="Bravo">
         <data key="actors">2</data>
      </edge>
      <edge source="Charlie" target="Delta">
         <data key="actors">1</data>
      </edge>
      <node id="Delta"/>
      <edge source="Delta" target="Alpha">
         <data key="actors">1</data>
      </edge>
      <edge source="Delta" target="Charlie">
         <data key="actors">1</data>
      </edge>
      <node id="Echo"/>
   </graph>
</graphml>

これは、あなたが探している結果である可能性があります (GraphML オンライン ビューアーが見つからなかったので、確信が持てません)。

ただし、上記のグラフでは、各エッジが 2 回 (方向ごとに 1 回) 表示されます。それが問題である場合は、代わりにこれを行うことで解消できます。

XSLT1.0

<xsl:template match="/movies">
    <graphml xmlns="http://graphml.graphdrawing.org/xmlns"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
        <key id="actors" for="edge" attr.name="actors" attr.type="int"/>
        <graph id="movies" edgedefault="undirected">
            <xsl:for-each select="movie">
                <xsl:variable name="source" select="." />
                <node id="{title}"/>
                    <xsl:for-each select="following-sibling::movie[actors/actor=$source/actors/actor]">
                        <edge source="{$source/title}" target="{title}">
                            <data key="actors">
                                <xsl:value-of select="count(actors/actor[.=$source/actors/actor])"/>
                            </data>
                        </edge>
                    </xsl:for-each>
            </xsl:for-each>
        </graph>
    </graphml>
</xsl:template>

</xsl:stylesheet>

次の結果を取得します。

<?xml version="1.0" encoding="UTF-8"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
   <key id="actors" for="edge" attr.name="actors" attr.type="int"/>
   <graph id="movies" edgedefault="undirected">
      <node id="Alpha"/>
      <edge source="Alpha" target="Bravo">
         <data key="actors">2</data>
      </edge>
      <edge source="Alpha" target="Charlie">
         <data key="actors">1</data>
      </edge>
      <edge source="Alpha" target="Delta">
         <data key="actors">1</data>
      </edge>
      <node id="Bravo"/>
      <edge source="Bravo" target="Charlie">
         <data key="actors">2</data>
      </edge>
      <node id="Charlie"/>
      <edge source="Charlie" target="Delta">
         <data key="actors">1</data>
      </edge>
      <node id="Delta"/>
      <node id="Echo"/>
   </graph>
</graphml>
于 2015-02-05T00:24:33.580 に答える