[英]Move xml nodes between parents and delete duplicates - xslt 2.0
我有一个xml,如下所示,想1)如果属性名称匹配,则将“数据”节点中的值移至“标头”,或2)如果名称属性与使用xsl转换的标头中的现有节点相同,则删除“数据”下的节点, 如果可能的话。 任何帮助将不胜感激。
初始xml:
<HEADER>
<KEY name="child1" value="value1" />
<KEY name="child2" value="value2" />
<KEY name="child3" value="value3" />
<KEY name="child4" value="value4" />
</HEADER>
<DATA>
<KEY name="child1" value="value1.data" />
<KEY name="child3" value="value3.data" />
<KEY name="child5" value="value5" />
<KEY name="child7" value="value7" />
</DATA>
如果子节点5是要移动的节点,则结果为...转换后:
<HEADER>
<KEY name="child1" value="value1" />
<KEY name="child2" value="value2" />
<KEY name="child3" value="value3" />
<KEY name="child4" value="value4" />
<KEY name="child5" value="value5" />
</HEADER>
<DATA>
<KEY name="child7" value="value7" />
</DATA>
当前的xsl:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output omit-xml-declaration="no" method="xml" indent="yes" />
<!-- <xsl:variable name="ReplaceLiveDate" select="false()" /> -->
<xsl:variable name="ReplaceLiveDate" select="true()" />
<xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
<!-- base identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- in HEADER: output ROLE sorted by @name -->
<xsl:template match="HEADER">
<xsl:copy>
<xsl:apply-templates select="KEY">
<xsl:sort select="translate(@name, $smallcase, $uppercase)" order="ascending" />
<!-- <xsl:sort select="@name" /> -->
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<!-- in DATA: output KEY sorted by @name -->
<xsl:template match="DATA">
<xsl:copy>
<xsl:apply-templates select="KEY">
<xsl:sort select="translate(@name, $smallcase, $uppercase)" order="ascending" />
<!-- <xsl:sort select="@name" /> -->
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
我有以下删除节点的方法,但不确定仅在标头部分中存在该节点的情况下如何执行此操作
<!-- remove processing nodes -->
<xsl:template match="KEY[starts-with(@name, 'child1')]"/>
有很多方法可以进行这种转换,但是在这种情况下,我认为明智的选择是使用xslt 键功能,请参见此处的简要说明。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output omit-xml-declaration="no" method="xml" indent="yes" />
<!-- <xsl:variable name="ReplaceLiveDate" select="false()" /> -->
<xsl:variable name="ReplaceLiveDate" select="true()" />
<xsl:variable name="smallcase" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
<!-- index all the KEY element of the HEADER -->
<xsl:key name='head' match='HEADER/KEY' use='@name' />
<!-- base identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match='HEADER'>
<xsl:copy>
<!-- move the child5 'KEY element' under the header -->
<xsl:copy-of select="//DATA/KEY[@name = 'child5']"/>
<!-- apply to childs -->
<xsl:apply-templates select="KEY">
<xsl:sort select="translate(@name, $smallcase, $uppercase)" order="ascending" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<!-- delete key nodes duplicated in Header, that is elments not indexed by the 'head' key -->
<xsl:template match="DATA/KEY[key('head',@name)]">
</xsl:template>
<!-- delete the node to be moved -->
<xsl:template match="DATA/KEY[@name = 'child5']" />
</xsl:stylesheet>
为简单起见,上面的样式表不会按字母顺序对标题键进行排序,如果确实需要,则必须进行执行排序 。
我试图保留尽可能多的原始样式表,但是按照这种方式,我没有找到其他解决方案。
如果要按@name属性对键进行排序,则在模板下方
<xsl:template match='HEADER'>
<xsl:variable name='unsorted_keys'>
<xsl:copy-of select="//DATA/KEY[@name = 'child5']"/>
<!-- apply to childs -->
<xsl:apply-templates select="KEY">
</xsl:apply-templates>
</xsl:variable>
<xsl:copy>
<!-- make sure to copy HEADER attributes -->
<xsl:apply-templates select='@*'/>
<!-- perform sort -->
<xsl:perform-sort select="$unsorted_keys/KEY">
<xsl:sort select="translate(@name, $smallcase, $uppercase)" order="ascending" />
</xsl:perform-sort>
</xsl:copy>
</xsl:template>
希望这可以帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.