XSL从一个元素剪切文本并创建新元素[key |价值]&将此文本粘贴到值内

时间:2014-01-10 10:39:48

标签: xml xslt xslt-2.0

我正在尝试在XSL中进行剪切和粘贴,但我无法使其工作。我想从一个元素剪切文本,然后创建新元素[key |值]并将此文本粘贴为给定键的值。

输入xml看起来像这样

<root>
   <payload>blabla</payload>
   <metadata>
      <metadata-element>
          <key>some-key</key>
          <value>some-value</value>
      </metadata-element>
   </metadata>
</root>

我希望实现的是这样的

<root>
   <payload></payload>
   <metadata>
      <metadata-element>
          <key>some-key</key>
          <value>some-value</value>
      </metadata-element>
   </metadata>
   <metadata>
       <metadata-element>
           <key>some-other-key</key>
           <value>blabla</value>
       </metadata-element>
   </metadata>
</root>

                                       一些-其他键                                                                                                                           

我的XSL模板看起来像这样

<axsl:template match="root/metadata">
  <axsl:copy>
     <axsl:apply-templates select="@*|node()"/>
     <metadata-element>
        <key>some-other-key</key>
        <value>
           <axsl:template match="root/payload">
              <axsl:copy>
                 <axs:apply-templates/>
              </axsl:copy>
        </value>
     </metadata-element>
  </axsl:copy>

不是xsl的忠实粉丝...任何帮助赞赏:) 谢谢

1 个答案:

答案 0 :(得分:1)

当你看到这样的问题时,你首先想到的应该是使用XSLT身份模板(你可能已经在XSLT中使用了它,但是你还没有展示XSLT的完整示例)

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

这意味着您只需要为要更改的节点编写匹配的模板。您应该将“剪切和粘贴”视为两个单独的更改。第一个更改是从有效内容元素中删除文本,第二个更改是将新的子元素添加到元素。

要更改有效负载元素,您可以编写这样的模板

<xsl:template match="payload">
  <xsl:copy>
    <xsl:apply-templates select="@*"/>
  </xsl:copy>
</xsl:template>

这会复制元素及其属性,从而忽略文本(请记住,文本节点是元素的子节点)。

更好的是,只需编写一个模板来忽略有效负载元素下的文本节点

<xsl:template match="payload/text()" />

对于第二个更改,您要向 root 元素添加一个新子项(可能仅在存在有效负载元素时才会这样。因此,您的模板匹配看起来像此

<xsl:template match="root[payload != '']">

然后,它只是一个修改身份模板的情况,但有额外的代码来显式添加你的新孩子(及其所有后代)

<xsl:copy>
  <xsl:apply-templates select="@*|node()"/>
  <metadata>
    <metadata-element>
      <key>some-other-key</key>
      <value><xsl:value-of select="payload" /></value>
    </metadata-element>
  </metadata>
</xsl:copy>

试试这个XSLT

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

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

  <xsl:template match="payload/text()" />

  <xsl:template match="root[payload != '']">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
      <metadata>
        <metadata-element>
          <key>some-other-key</key>
          <value><xsl:value-of select="payload" /></value>
        </metadata-element>
      </metadata>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>