2011-04-25 136 views
1

artworks.xml文件:XML文件轉換

<artworks> 
    <artwork> 
    <title>Adoration of the Magi</title> 
    <author>GHIRLANDAIO, Domenico</author> 
    <date>1487</date> 
    <technique>Tempera on wood, diameter: 171 cm</technique> 
    <location>Galleria degli Uffizi, Florence</location> 
    <form>painting</form> 
    <type>religious</type> 
    </artwork> 
</artworks> 

author.xml文件:

<authors> 
    <author> 
    <name>AMADEO, Giovanni Antonio</name> 
    <born-died>b. ca. 1447, Pavia, d. 1522, Milano</born-died> 
    <nationality>Italian</nationality> 
    <biography>Giovanni Antonio Amadeo was an Italian early Renaissance sculptor</biography> 
    </author> 
<authors> 

的Output.xml文件:

<authors> 
    <author> 
     <name>AMADEO, Giovanni Antonio</name> 
     <born-died>b. ca. 1447, Pavia, d. 1522, Milano</born-died> 
     <nationality>Italian</nationality> 
     <biography>Giovanni Antonio Amadeo was an Italian early Renaissance sculptor</biography> 
    <artworks form="architecture"> 
     <artwork date="1473"> 
      <title>Faهade of the church</title> 
      <technique>Marble</technique> 
      <location>Certosa, Pavia</location> 
     </artwork> 
    </artworks> 
    </author> 
</authors> 

的artworks.xml作者作品是一個外鍵,引用authors.xml作者 條目。

我想合併這兩個XML文檔並創建一個新的XML文件,其中 應爲每個作者存儲以下信息:名稱,出生死亡,國籍, 傳記和所有作品。藝術品按表格分組,然後按日期排序。對於 每個藝術品,標題,技術和位置存儲

是challanging:)

回答

0

我得到儘可能使用document()功能您的問題的合流部分:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output indent="yes" method="xml" /> 
    <xsl:template match="authors"> 
     <authors> 
      <xsl:for-each select="author"> 
       <author> 
        <xsl:copy-of select="name" /> 
        <xsl:copy-of select="born-died" /> 
        <xsl:copy-of select="nationality" /> 
        <xsl:copy-of select="biography" /> 
        <xsl:variable name="name" select="name" /> 
        <artworks> 
         <xsl:for-each select="document('artworks.xml')//artwork[author=$name]"> 
         <artwork> 
          <xsl:copy-of select="title" /> 
          <xsl:copy-of select="date" /> 
          <xsl:copy-of select="technique" /> 
          <xsl:copy-of select="location" /> 
          <xsl:copy-of select="form" /> 
          <xsl:copy-of select="type" /> 
         </artwork> 
         </xsl:for-each> 
        </artworks> 
       </author> 
      </xsl:for-each> 
     </authors> 
    </xsl:template> 
</xsl:stylesheet> 

我使用Intel's XSLT command line tool進行轉換。這裏的命令行:

soaexslt2.exe merge.xsl authors.xml output.xml 
1

這是訣竅。它顯示了許多有用的XSLT技術 - 延伸的恆等變換,Muenchian分組的,使用document()到從輔助文件中的數據合併,抑制空元素的輸出 - 這使得它值得在滿工作了:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:variable name="authors" 
       select="document('authors.xml')/authors/author"/> 
    <xsl:variable name="artworks" 
       select="/artworks/artwork"/> 

    <!-- use Muenchian grouping to create a list of all distinct form values --> 
    <xsl:key name="form-key" 
      match="/artworks/artwork/form" 
      use="."/> 
    <xsl:variable name="forms" 
       select="/artworks/artwork/form[generate-id(.) = generate-id(key('form-key', .)[1])]"/> 

    <xsl:template match="/"> 
    <authors> 
     <xsl:apply-templates select="$authors"/> 
    </authors> 
    </xsl:template> 

    <xsl:template match="author"> 
    <xsl:variable name="artworks-for-author" 
        select="$artworks[author=current()/name]"/> 
    <!-- only create an author element if it will contain at least one artwork --> 
    <xsl:if test="$artworks-for-author"> 
     <author> 
     <xsl:apply-templates select="name|born-died|nationality|biography"/> 
     <xsl:for-each select="$forms"> 
      <!-- only create an artworks element if there's at least one artwork with this form --> 
      <xsl:variable name="artworks-with-form" 
         select="$artworks-for-author[form=current()]"/> 
      <xsl:if test="$artworks-with-form"> 
      <artworks form="{current()}"> 
       <xsl:apply-templates select="$artworks-with-form"> 
       <xsl:sort select="date"/> 
       </xsl:apply-templates> 
      </artworks> 
      </xsl:if> 
     </xsl:for-each> 
     </author> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template match="artwork"> 
    <xsl:apply-templates select="title|technique|location"/> 
    </xsl:template> 

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

</xsl:stylesheet> 
2

甲完整的解決方案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:variable name="authors" select="document('author.xml')" /> 
    <xsl:variable name="artworks" select="/artworks/artwork" /> 
    <xsl:key name="byNameForm" match="artworks/artwork" 
           use="concat(author, '|', form)" /> 
    <xsl:template match="/"> 
     <authors> 
      <xsl:apply-templates select="$authors/*/author" /> 
     </authors> 
    </xsl:template> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()" /> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="author"> 
     <author> 
      <xsl:apply-templates /> 
      <xsl:apply-templates select="$artworks[author=current()/name]" /> 
     </author> 
    </xsl:template> 
    <xsl:template match="artworks/artwork" /> 
    <xsl:template match="artworks/artwork[generate-id()= 
      generate-id(key('byNameForm', concat(author, '|', form))[1])]"> 
     <artworks form="{form}"> 
      <xsl:apply-templates 
       select="key('byNameForm', concat(author, '|', form))" 
       mode="form"> 
       <xsl:sort select="date" data-type="number" /> 
      </xsl:apply-templates> 
     </artworks> 
    </xsl:template> 
    <xsl:template match="artworks/artwork" mode="form"> 
     <artwork date="{date}"> 
      <xsl:apply-templates select="title|technique|location" /> 
     </artwork> 
    </xsl:template> 
</xsl:stylesheet> 

輸入:

<artworks> 
    <artwork> 
     <title>Adoration of the Magi</title> 
     <author>GHIRLANDAIO, Domenico</author> 
     <date>1486</date> 
     <technique>Tempera on wood, diameter: 171 cm</technique> 
     <location>Galleria degli Uffizi, Florence</location> 
     <form>painting</form> 
     <type>religious</type> 
    </artwork> 
    <artwork> 
     <title>Something</title> 
     <author>AMADEO, Giovanni Antonio</author> 
     <date>1484</date> 
     <technique>Marble</technique> 
     <location>Mars</location> 
     <form>sculpture</form> 
     <type>religious</type> 
    </artwork> 
    <artwork> 
     <title>Something2</title> 
     <author>AMADEO, Giovanni Antonio</author> 
     <date>1487</date> 
     <technique>Glue</technique> 
     <location>New York</location> 
     <form>sculpture</form> 
     <type>secular</type> 
    </artwork> 
    <artwork> 
     <title>Something3</title> 
     <author>AMADEO, Giovanni Antonio</author> 
     <date>1482</date> 
     <technique>Some tech</technique> 
     <location>Mars</location> 
     <form>paper</form> 
     <type>religious</type> 
    </artwork> 
</artworks> 

和:

<authors> 
    <author> 
     <name>AMADEO, Giovanni Antonio</name> 
     <born-died>b. ca. 1447, Pavia, d. 1522, Milano</born-died> 
     <nationality>Italian</nationality> 
     <biography>Giovanni Antonio Amadeo was an Italian early 
      Renaissance sculptor</biography> 
    </author> 
    <author> 
     <name>GHIRLANDAIO, Domenico</name> 
     <born-died>b. ca. 1447, Pavia, d. 1522, Venice</born-died> 
     <nationality>Italian</nationality> 
     <biography>N/A</biography> 
    </author> 
</authors> 

輸出:

<authors> 
    <author> 
     <name>AMADEO, Giovanni Antonio</name> 
     <born-died>b. ca. 1447, Pavia, d. 1522, Milano</born-died> 
     <nationality>Italian</nationality> 
     <biography>Giovanni Antonio Amadeo was an Italian early 
      Renaissance sculptor</biography> 
     <artworks form="sculpture"> 
      <artwork date="1484"> 
       <title>Something</title> 
       <technique>Marble</technique> 
       <location>Mars</location> 
      </artwork> 
      <artwork date="1487"> 
       <title>Something2</title> 
       <technique>Glue</technique> 
       <location>New York</location> 
      </artwork> 
     </artworks> 
     <artworks form="paper"> 
      <artwork date="1482"> 
       <title>Something3</title> 
       <technique>Some tech</technique> 
       <location>Mars</location> 
      </artwork> 
     </artworks> 
    </author> 
    <author> 
     <name>GHIRLANDAIO, Domenico</name> 
     <born-died>b. ca. 1447, Pavia, d. 1522, Venice</born-died> 
     <nationality>Italian</nationality> 
     <biography>N/A</biography> 
     <artworks form="painting"> 
      <artwork date="1486"> 
       <title>Adoration of the Magi</title> 
       <technique>Tempera on wood, diameter: 171 cm</technique> 
       <location>Galleria degli Uffizi, Florence</location> 
      </artwork> 
     </artworks> 
    </author> 
</authors> 

編輯:更新由作者來驅動的處理,所以,即使作者沒有任何作品將包括在內。

+0

+1非常好的答案:遍歷作者和按作者+表格分組作品。一些未成年人:如果您要覆蓋身份規則,請使用''而不是''如果你打算使用push風格,你可以像'select ='一樣完成它$ ART [generate-id()= generate-id(key('byNameForm',concat(current()/name,'|',form))[1])]''或者您可以爲作者使用第二個鍵(這將在外部文檔上添加鍵的示例)。 – 2011-04-25 19:49:52