我已经有一段时间了 - 已经让XSLT工作了,删除了不需要的节点和属性,但是其中有一部分让我失望。
我的想法是我有3个元素,每个元素有1个属性,我想将属性从第二个和第三个元素移动到第一个元素(并删除第二个和第三个元素)。
[Snippet 1]来自:
<info>
<id name="Tim"/>
<address addr="1 Witchwood Close"/>
<phone num="01234 567 891"/>
</info>
[Snippet 2] To:
<info>
<id name="Tim" addr="1 Witchwood Close" num="01234 567 891"/>
</info>
xslt目前(并且已经输出了如上所述的xml片段):
<xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<!-- Identity Transform -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!-- remove 'fullname' node to promote sub-nodes -->
<xsl:template match="fullname">
<xsl:apply-templates"/>
</xsl:template>
<!-- Promote 'phone' node to 'info' (from 'address' sub-node) -->
<xsl:template match="address[phone]">
<xsl:copy>
<xsl:apply-templates select="node()[not(self::phone)]|@*"/>
</xsl:copy>
<xsl:apply-templates select="phone"/>
</xsl:template>
<!-- Drop unwanted elements & attributes -->
<xsl:template match="addressline2|addressline3|postcode|@middlename"/>
</xsl:stylesheet>
任何指针?
非常感谢
修改
包括来自Eero的XSLT片段,它似乎没有做任何事情(即我获得与[Snippet 1]中相同的XML),但是玩弄它:
<xsl:template match="id">
<xsl:copy>
<xsl:apply-templates select="@* | following-sibling::*/>
</xsl:copy>
</xsl:template>
制备:
<info>
<id name="Tim">
<address addr="1 Witchwood Close"/>
<phone num="01234 567 891"/>
</id>
<address addr="1 Witchwood Close"/>
<phone num="01234 567 891"/>
</info?
如果将兄弟姐妹改为
following-sibling::*|@*
我得到了相同的结果。那么为什么下面的兄弟语句包含'/'而不是'|'没有进行任何改造?很明显我错过了一些简单的东西。
编辑2(包含解决方案)
我想我已经对它进行了分类。意识到我需要在XPath上生成(现在可能非常明显!)我真的不知道wtf是怎么回事,我想出了这个片段:
<xsl:template match="id">
<xsl:copy>
<xsl:apply-templates select="@name | following-sibling::*//@addr"/>
<xsl:apply-templates select="@name | @addr | following-sibling::*//@num"/>
</xsl:copy>
</xsl:template>
产生:
<info>
<id name="Tim" addr="1 Witchwood Close" num="01234 567 891"/>
</info>
这正是我追求的!我认为这可能不是最强烈的优雅做事方式,但它似乎完成了工作......只有一个小例外。 偶尔,输出将是(没有明显的原因,为什么那个而不是另一个):
<info>
<id name="Tim" addr="1 Witchwood Close" num="01234 567 891"/>
<address addr="1 Witchwood Close"/>
</info>
尽管在复制后删除了节点。这不是一个大问题,因为SQL XML导入设置为仅导入由'id'标识的行上的字段,因此忽略'address'行。
我已将Eero的答案标记为“已接受”,因为这是我最终解决问题的方向,但我的代码实际上是丑陋的。欢迎评论如何减少对它的影响!
谢谢!
答案 0 :(得分:1)
像这样的简单样式表可以解决这个问题:
<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="*"/>
<xsl:template match="id">
<xsl:copy>
<!--
Apply the attributes of the current node and the attributes of all
following siblings (in this case, <address> and <phone>)
-->
<xsl:apply-templates select="@* | following-sibling::*/@*"/>
</xsl:copy>
</xsl:template>
<!-- Drop the <address> and <phone> elements -->
<xsl:template match="address | phone"/>
<!--
Identity transform: copy attributes and elements from input document to output
document as is
-->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>