[英]Move xml element with xslt
我有一個這樣的xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<i xmlns="http://stuff.com" >
<v>
<iNumber>0118</iNumber>
<s>1</s>
<a>24</a>
<p>2175</p>
<p>2175</p>
<p>4534</p>
</v>
</i>
但是我需要導出看起來像這樣。
<?xml version="1.0" encoding="UTF-8"?>
<i xmlns="http://stuff.com" >
<v>
<iNumber>0118</iNumber>
<s>1</s>
<a>24</a>
<p>2175</p>
</v>
<v>
<iNumber>0118</iNumber>
<s>1</s>
<a>24</a>
<p>2175</p>
</v>
<iNumber>0118</iNumber>
<s>1</s>
<a>24</a>
<p>4534</p>
</v>
</i>
我是xslt的新手,所以我需要一些有關轉換此xml的幫助
這是我的嘗試:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:stuff="http://stuff.com" exclude-result-prefixes="stuff">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="stuff:v">
<xsl:copy>
<xsl:copy-of select="ancestor::stuff:v/stuff:p"/>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我已經更新了問題以顯示我的嘗試
這應該可以解決問題:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:stuff="http://stuff.com" exclude-result-prefixes="stuff">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="stuff:v">
<xsl:for-each select="stuff:p">
<xsl:apply-templates select="ancestor::stuff:v" mode="copying">
<xsl:with-param name="pId" select="generate-id()" />
</xsl:apply-templates>
</xsl:for-each>
</xsl:template>
<xsl:template match="stuff:v" mode="copying">
<xsl:param name="pId" />
<xsl:copy>
<xsl:apply-templates select="@*|node()">
<xsl:with-param name="pId" select="$pId" />
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="stuff:p">
<xsl:param name="pId"/>
<xsl:if test="generate-id() = $pId">
<xsl:copy-of select="." />
</xsl:if>
</xsl:template>
</xsl:stylesheet>
一些解釋。 默認情況下,第一個匹配node()|@*
模板只是復制內容。
遇到stuff:v元素時,匹配stuff:v
的第二個模板將接管。 它將遍歷其中的所有stuff:p元素,並為每個元素將匹配的模板應用於其stuff:v祖先。 但是,它進入我稱為“復制”的模式,並使用參數pId
調用模板,參數pId
是p元素的ID。 XML中的每個元素都有一些唯一標識它的隱式ID。
這樣,我們最終到達了下一個模板,該模板也匹配stuff:v
但僅在“復制”模式下。 它接受一個pId參數,復制v元素,然后將模板應用於其所有屬性和子節點,不再使用“復制”模式, 而是使用pId參數 。 最后一部分至關重要。
最終的模板與stuff:p
相匹配,但是僅當該元素的id與pId參數中指定的ID相同時才將其復制。
因此,基本上,我們進入stuff:v,遍歷其中的每個stuff:p,對於它們中的每一個,它再次以不同的模式進入stuff:v,以匹配另一個模板(否則它將無限遞歸),然后從那里復制除東西以外的所有內容:p元素都要求它們與傳遞到模板中的參數匹配。
為什么不簡單地做:
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:stuff="http://stuff.com"
exclude-result-prefixes="stuff">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/stuff:i">
<i xmlns="http://stuff.com">
<xsl:for-each select="stuff:v/stuff:p">
<v>
<xsl:copy-of select="../*[not(self::stuff:p)]"/>
<xsl:copy-of select="."/>
</v>
</xsl:for-each>
</i>
</xsl:template>
</xsl:stylesheet>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.