XSLT复制子节点并将其转换为父节点

时间:2017-05-10 09:41:35

标签: xml xslt

我有以下输入:

<Article>
<title>Apple</title>
<number>119.057</number>
<price>90.8</price>
  <option>
    <Article>
        <title>Apple Green</title>
        <price>144.2</price>
        <number>119.086</number>
    </Article>
  </option>
</Article>
<Article>
      <title>Coconut</title>
      <number>120.882</number>
      <price>10.00</price>
</Article>
<Article>
      <title>Pinapple</title>
      <number>120.883</number>
      <price>19.00</price>
 </Article>

它应该是这样的:

 <Article>
   <title>Apple</title>
   <number>119.057</number>
   <price>90.8</price>
 </Article>
 <Article>
   <title>Apple Green</title>
   <price>144.2</price>
   <number>119.086</number>
 </Article>
 <Article>
   <title>Coconut</title>
   <number>120.882</number>
   <price>10.00</price>
 </Article>
 <Article>
   <title>Pinapple</title>
   <number>120.883</number>
   <price>19.00</price>
 </Article>

到目前为止我的尝试:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml" />
<xsl:template match="root/Article">
    <xsl:apply-templates/>
</xsl:template>

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

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

实际上我需要删除选项-Tag和Child-Tags应该成为Article-Tags。 这样所有节点都在树中的同一级别上 最后删除选项Tag。

感谢您的输入!

2 个答案:

答案 0 :(得分:1)

您写道:“我需要删除options标记,并且应该删除其子标记 变成({chilren of} Article标签“。

然后这样做,但稍作修正:你要匹配的标签 (并在输出中删除)为option(不是options)。

<xsl:template match="Article/option">
  <xsl:apply-templates />
</xsl:template>

请注意与身份模板的相似性。主要区别在于 没有xsl:copy标记(可能会复制原始option标记)。

修改

最初我只提供了模板。下面是完整的脚本:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes" method="xml" />

  <xsl:template match="Article/option">
    <xsl:apply-templates />
  </xsl:template>

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

它确实生成了所需的输出。

编辑2

另一个解决方案。它仅复制option内容,但要保留 正确的XML格式,我添加了一个“信封”根(main)标记。

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

  <xsl:template match="/Article">
    <!-- This matches only the root Article tag, not its grandson -->
    <main>  <!-- You need to have a main (root) tag -->
      <!-- Output only the option content -->
      <xsl:apply-templates select="option"/>
    </main>
  </xsl:template>

  <xsl:template match="option">
    <xsl:apply-templates/>
  </xsl:template>

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

答案 1 :(得分:0)

给出格式良好的输入,例如:

<强> XML

<Articles>
  <Article>
    <title>Apple</title>
    <number>119.057</number>
    <price>90.8</price>
    <option>
      <Article>
        <title>Apple Green</title>
        <price>144.2</price>
        <number>119.086</number>
      </Article>
    </option>
  </Article>
  <Article>
    <title>Coconut</title>
    <number>120.882</number>
    <price>10.00</price>
  </Article>
  <Article>
    <title>Pinapple</title>
    <number>120.883</number>
    <price>19.00</price>
  </Article>
</Articles>

以下样式表:

XSLT 1.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:strip-space elements="*"/>

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

<xsl:template match="Article">
    <xsl:copy>
        <xsl:apply-templates select="*[not(self::option)]"/>
    </xsl:copy>
    <xsl:apply-templates select="option"/>
</xsl:template>

<xsl:template match="option">
    <xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>

会将option节点从Article的子节点转换为其兄弟节点,返回:

<强>结果

<?xml version="1.0" encoding="UTF-8"?>
<Articles>
  <Article>
    <title>Apple</title>
    <number>119.057</number>
    <price>90.8</price>
  </Article>
  <Article>
    <title>Apple Green</title>
    <price>144.2</price>
    <number>119.086</number>
  </Article>
  <Article>
    <title>Coconut</title>
    <number>120.882</number>
    <price>10.00</price>
  </Article>
  <Article>
    <title>Pinapple</title>
    <number>120.883</number>
    <price>19.00</price>
  </Article>
</Articles>