通过 xslt 转换将 XML 文件转换为 output.xml

发布于 2024-11-02 21:38:06 字数 1770 浏览 1 评论 0原文

arts.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 文件,其中 应存储每位作者的以下信息:姓名、出生日期、国籍、 传记和所有艺术品。艺术品按形式分组,然后按日期排序。为了 每件艺术品、标题、技术和位置的存储

都具有挑战性:)

artworks.xml file:

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

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

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

The artworks.xml artwork author is a foreign key, referencing the authors.xml author
entries.

I would like to merge these two XML documents and create a new XML file, in which the
following information should be stored for each author: name, born-died, nationality,
biography, and all artworks. The artworks are grouped by form and then sorted on date. For
each artwork, title, technique, and location are stored

it is challanging : )

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

看海 2024-11-09 21:38:06

完整的解决方案:

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

编辑:更新以驱动作者处理,这样即使没有任何艺术品的作者也会被包括在内。

A complete solution:

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

Input:

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

And:

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

Output:

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

Edit: Updated to drive processing by author, so that even authors without any artworks will be included.

梨涡少年 2024-11-09 21:38:06

这可以解决问题。它演示了许多有用的 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>

This does the trick. It demonstrates a number of useful XSLT techniques - extending the identity transform, Muenchian grouping, using document() to merge data from a secondary document, suppressing output of empty elements - which made it worth working out in full:

<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>
无所的.畏惧 2024-11-09 21:38:06

我使用 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 的 XSLT 命令行工具来进行转换。这是命令行:

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

I got as far as the merging part of your problem using the document() function:

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

I used Intel's XSLT command line tool to do the transform. Here's the command line:

soaexslt2.exe merge.xsl authors.xml output.xml
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文