[英]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.