如何使用XSLT轻松地将xml转换为其他格式

时间:2018-05-25 11:20:53

标签: xml xslt

目前正试图在实际环境中教自己基本的XSLT - 想知道改变这个的最简单方法是什么:

<fig id="vid1" position="float" fig-type="video">
<label>Video 1</label>
<caption><p>Test video 1</p></caption>
<media xlink:href="test1.mp4" id="test1" mime-subtype="mp4" content-type="play-in-place"/>
</fig>

进入这种格式,同时添加应该在每次转换时输出的样板文本(external-host-filename,Video player)。

<media id="vid1" xlink:href="test1.mp4" xlink:role="external-host-filename" content-type="play-in-place">
<object-id pub-id-type="media-player-id">Video Player</object-id>
<object-id pub-id-type="other" content-type="media-stream-id">test 1</object-id>
<label>Video 1</label>
<caption><p>Test video 1</p></caption>
</media>

任何输入都会很棒,谢谢!

1 个答案:

答案 0 :(得分:0)

让我们从您的源XML开始。 正如您所写,可以通过多个 fig节点进行嵌入 在一些单个根元素中,我将其称为root

另一个要求是每个使用的命名空间必须在某个地方声明, 例如在根元素中。

所以源XML,包括简单的单个(你的)fig元素 可以如下:

<root xmlns:xlink="urn:xlink">
  <fig id="vid1" position="float" fig-type="video">
    <label>Video 1</label>
    <caption><p>Test video 1</p></caption>
    <media xlink:href="test1.mp4" id="test1" mime-subtype="mp4" content-type="play-in-place"/>
  </fig>
</root>

现在转到XSLT脚本。

首先,您必须在开场stylesheet标记中重复 使用的每个命名空间,例如:xmlns:xlink="urn:xlink"

要定义样板文本,您可以使用xsl:param元素, 定义他们的名字和价值,例如:

<xsl:param name="role" select="'external-host-filename'"/>
<xsl:param name="Object1" select="'Video Player'"/>

然后你应该编写一个匹配fig的模板,生成一个media元素 具有适当的属性和内容。例如。要创建id属性,您可以写:

<xsl:attribute name="id" select="@id"/>

有时可以从源复制属性,例如

<xsl:copy-of select="media/@content-type"/>

现在是一项发明:因为你的输出要包含两个 object-id 元素,让我们编写一个模板,以便在必要时生成它 形式参数:

<xsl:template name="object">
  <xsl:param name="pub-type"/>
  <xsl:param name="content-type" required="no"/>
  <xsl:param name="content"/>
  <object-id>
    <xsl:attribute name="pub-id-type" select="$pub-type"/>
    <xsl:if test="$content-type != ''">
      <xsl:attribute name="content-type" select="$content-type"/>
    </xsl:if>
    <xsl:value-of select="$content"/>
  </object-id>
</xsl:template>

并使用适当的实际参数调用两次(见下文)。

此模板的最后一部分是将两个源元素复制到 输出,使用copy-of。 为了缩短脚本,我在一个copy-of语句中写了它。

并且不要忘记身份模板

所以整个脚本可能如下所示:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xlink="urn:xlink">
  <xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
  <xsl:param name="role" select="'external-host-filename'"/>
  <xsl:param name="Object1" select="'Video Player'"/>

  <xsl:template match="fig">
    <media>
      <xsl:attribute name="id" select="@id"/>
      <xsl:attribute name="xlink:href" select="media/@xlink:href"/>
      <xsl:attribute name="xlink:role" select="$role"/>
      <xsl:copy-of select="media/@content-type"/>
      <xsl:call-template name="object">
        <xsl:with-param name="pub-type" select="'media-player-id'"/>
        <xsl:with-param name="content" select="$Object1"/>
      </xsl:call-template>
      <xsl:call-template name="object">
        <xsl:with-param name="pub-type" select="'other'"/>
        <xsl:with-param name="content-type" select="'media-stream-id'"/>
        <xsl:with-param name="content" select="'test 1'"/>
      </xsl:call-template>
      <xsl:copy-of select="label, caption"/>
    </media>
  </xsl:template>

  <xsl:template name="object">
    <xsl:param name="pub-type"/>
    <xsl:param name="content-type" required="no"/>
    <xsl:param name="content"/>
    <object-id>
      <xsl:attribute name="pub-id-type" select="$pub-type"/>
      <xsl:if test="$content-type != ''">
        <xsl:attribute name="content-type" select="$content-type"/>
      </xsl:if>
      <xsl:value-of select="$content"/>
    </object-id>
  </xsl:template>

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

有关工作示例,请参阅http://xsltransform.net/nb9MWtn