2012-09-18 91 views
5

我已經創建了一個XSLT,我想知道如何在一組標籤之間複製所有節點,並在底部添加另一個標籤。我創建了XSLT,它具有確定要添加哪個標記以及應該調用哪些標記的邏輯。然而,我現在得到的問題是我無法複製所有其他標籤。下面是有問題的文件:XSLT - 複製所有其他節點,添加1個新節點

XSLT

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/csvImportSchema"> 
     <csvImportSchema> 
      <xsl:for-each select="payload"> 
       <payload> 
        <xsl:copy-of select="@*"/> 
        <xsl:variable name="ean"> 
         <xsl:value-of select="ean"/> 
        </xsl:variable> 
        <xsl:for-each select="../product"> 
         <xsl:if test="ean = $ean"> 
          <productId><xsl:value-of select="article"/></productId> 
         </xsl:if> 
        </xsl:for-each> 
       </payload> 
      </xsl:for-each> 
     </csvImportSchema> 
    </xsl:template> 

</xsl:stylesheet> 

INPUT

<?xml version="1.0" encoding="UTF-8"?> 
<csvImportSchema> 
    <payload> 
     <test>1</test> 
     <test2>2</test2> 
     <test3>3</test3> 
     <ean>1111111111</ean> 
     <productId/> 
    </payload> 
    <product> 
     <article>722619</article> 
     <ean>1111111111</ean> 
    </product> 
</csvImportSchema> 

電流輸出

<?xml version="1.0" encoding="utf-8"?> 
<csvImportSchema> 
    <payload> 
     <productId>722619</productId> 
    </payload> 
</csvImportSchema> 

所需的輸出

<?xml version="1.0" encoding="UTF-8"?> 
<csvImportSchema> 
    <payload> 
     <test>1</test> 
     <test2>2</test2> 
     <test3>3</test3> 
     <ean>1111111111</ean> 
     <productId>722619</productId> 
    </payload> 
</csvImportSchema> 

回答

7

這種短期和簡單改造

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="productId"> 
    <productId> 
    <xsl:value-of select="../../product/article"/> 
    </productId> 
</xsl:template> 
<xsl:template match="product"/> 
</xsl:stylesheet> 

時所提供的XML文檔應用:

<csvImportSchema> 
    <payload> 
     <test>1</test> 
     <test2>2</test2> 
     <test3>3</test3> 
     <ean>1111111111</ean> 
     <productId/> 
    </payload> 
    <product> 
     <article>722619</article> 
     <ean>1111111111</ean> 
    </product> 
</csvImportSchema> 

產生想要的,正確的結果

<csvImportSchema> 
    <payload> 
     <test>1</test> 
     <test2>2</test2> 
     <test3>3</test3> 
     <ean>1111111111</ean> 
     <productId>722619</productId> 
    </payload> 
</csvImportSchema> 

說明

  1. 「原樣」 的每個節點被選擇用於執行的量,identity rule副本。

  2. 重寫模板匹配product從輸出(通過它的空體)「刪除」該元素。

  3. 另一個壓倒一切的模板匹配productId,並從product/article中生成帶有文本節點子元素的此元素。

1

它應該是爲改變你的有效載荷xsl:copy-of select="@*"/

<xsl:copy-of select="*[local-name() != 'productId'] | @*"/> 

即簡單複製一切,除了productId,因爲你手動建立這個了。

這給了你所需要

<?xml version="1.0" encoding="utf-8"?> 
<csvImportSchema> 
    <payload> 
    <test>1</test> 
    <test2>2</test2> 
    <test3>3</test3> 
    <ean>1111111111</ean> 
    <productId>722619</productId> 
    </payload> 
</csvImportSchema> 
1

這XSLT應該做的工作和使用方式更加COPY標記和模板輸出。也許不要在一個xsl:template(我的意見)中做所有事情。

<?xml version="1.0" encoding="UTF-8"?> 
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="1.0"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/csvImportSchema"> 
     <xsl:copy> 
      <xsl:apply-templates select="*"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="csvImportSchema/payload/productId"> 
     <xsl:variable name="ean"> 
      <xsl:value-of select="../ean"/> 
     </xsl:variable> 
     <xsl:for-each select="../../product"> 
      <xsl:if test="ean = $ean"> 
       <productId><xsl:value-of select="article"/></productId> 
      </xsl:if> 
     </xsl:for-each> 
    </xsl:template> 

    <xsl:template match="csvImportSchema/product"> 
     <!-- do not copy --> 
    </xsl:template> 

    <xsl:template match="csvImportSchema/payload"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 
2

對您的代碼的一個觀察。

<xsl:variable name="ean"> 
    <xsl:value-of select="../ean"/> 
</xsl:variable> 

時,你可以這樣寫::

<xsl:variable name="ean" select="../ean"/> 

它不僅是冗長的,它也是令人難以置信的低效率:不是$ EAN結合到現有的節點,要解壓縮不要使用此現有節點的字符串值,形成具有該字符串值的文本節點,創建新的XML文檔樹,以及將此文本節點添加到此新文檔的內容中。 (我通過消除這個可怕的構造,使樣式表運行速度提高了3倍。)

+0

謝謝。我會牢記這一點。 – MMKD

相關問題