簡體   English   中英

使用xslt移動xml元素

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM