2012-11-24 64 views
1

基本上,這是我嘗試的邏輯。XSL轉換子節點的值不同

對於父節點(ByFirstNameSearchList或ByLastNameSearchList):

- 所有子元素的值是空的(value1-4),插入的%的值 - 當一個或任意子元素的已值,更換所有兄弟姐妹與NOVAL空值。

我有下面的XML:

<GetName> 
    <ByLastNameSearchList> 
     <Value1/> 
     <Value2/> 
     <Value3/> 
     <Value4/> 
     <Value5/> 
    </ByLastNameSearchList> 
    <ByFirstNameSearchList> 
     <Value1>String</Value1> 
     <Value2>String</Value2> 
     <Value3/> 
     <Value4/> 
     <Value5/> 
    </ByFirstNameSearchList> 
    </GetName> 

這就是我想要它看起來像:

<GetName> 
    <ByLastNameSearchList> 
     <Value1>%</Value1> 
     <Value2>%</Value2> 
     <Value3>%</Value3> 
     <Value4>%</Value4> 
     <Value5>%</Value5> 
    </ByLastNameSearchList> 
    <ByFirstNameSearchList> 
     <Value1>String</Value1> 
     <Value2>String</Value2> 
     <Value3>NOVAL</Value3> 
     <Value4>NOVAL</Value4> 
     <Value5>NOVAL</Value5> 
    </ByFirstNameSearchList> 
</GetName> 

我真的很感謝你幫助我。相信我,我用我有限的XSL知識嘗試了一切。

謝謝。

回答

0

這個樣式表

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

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

    <xsl:template match="ByFirstNameSearchList/* | ByLastNameSearchList/*"> 
     <xsl:copy> 
     <xsl:choose> 
      <xsl:when test="string-length(text()) gt 0"> 
       <xsl:value-of select="text()"/> 
      </xsl:when> 
      <xsl:when test="some $Value in ../* satisfies string-length($Value/text()) gt 0"> 
       <xsl:text>NOVAL</xsl:text> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:text>%</xsl:text> 
      </xsl:otherwise> 
     </xsl:choose> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

會產生你想要的輸出。

UPDATE:

這個版本是較爲通用的,因爲它不依賴於一個只包含一個字符串的非空元素:

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

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

    <xsl:template match="ByFirstNameSearchList/* | ByLastNameSearchList/*"> 
     <xsl:choose> 
     <xsl:when test="string-length(text()) gt 0"> 
      <xsl:copy-of select="."/> 
     </xsl:when> 
     <xsl:when test="some $Value in ../* satisfies string-length($Value/text()) gt 0"> 
      <xsl:copy> 
       <xsl:text>NOVAL</xsl:text> 
      </xsl:copy> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:copy> 
       <xsl:text>%</xsl:text> 
      </xsl:copy> 
     </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 
0

至於因爲這簡單的(無論是XSLT 2.0和XSLT 1.0):

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

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

<xsl:template match="/*/*/*[not(node())]"> 
    <xsl:copy>NOVAL</xsl:copy> 
</xsl:template> 

<xsl:template match="/*/*[not(*/node())]/*"> 
    <xsl:copy>%</xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

當這個變換所提供的XML文檔應用:

<GetName> 
    <ByLastNameSearchList> 
     <Value1/> 
     <Value2/> 
     <Value3/> 
     <Value4/> 
     <Value5/> 
    </ByLastNameSearchList> 
    <ByFirstNameSearchList> 
     <Value1>String</Value1> 
     <Value2>String</Value2> 
     <Value3/> 
     <Value4/> 
     <Value5/> 
    </ByFirstNameSearchList> 
</GetName> 

想要的,正確的結果產生:

<GetName> 
     <ByLastNameSearchList> 
      <Value1>%</Value1> 
      <Value2>%</Value2> 
      <Value3>%</Value3> 
      <Value4>%</Value4> 
      <Value5>%</Value5> 
     </ByLastNameSearchList> 
     <ByFirstNameSearchList> 
      <Value1>String</Value1> 
      <Value2>String</Value2> 
      <Value3>NOVAL</Value3> 
      <Value4>NOVAL</Value4> 
      <Value5>NOVAL</Value5> 
     </ByFirstNameSearchList> 
</GetName> 

說明

  1. 身份規則副本 「原樣」 爲其中每個節點它被選中執行。

  2. 模板覆蓋該是頂級元素的盛大的孩子和沒有孩子的任何元素的身份模板。這將複製元素並生成一個字符串值爲「NOVAL」的文本節點子。

  3. 第二個覆蓋模板,它覆蓋了標識模板和第一個覆蓋模板:匹配頂層元素的父子沒有包含子節點的子元素的任何元素。這將複製元素並生成一個字符串值爲字符串「%」的文本節點子元素。

請注意

  1. 這是一個純粹的 「推式」 轉變。

  2. 有沒有明確的條件指令(無xsl:choose,沒有xsl:when,沒有xsl:otherwise),沒有xsl:text甚至沒有xsl:apply-templates(除了在身份模板)。

  3. 沒有特殊的XPath 2.0表達式(some ... satisfies ...),因爲它們是不必要的。

  4. string-length()功能被使用。

+0

謝謝這就像一個魅力。只是一個問題。執行的順序是什麼?例如,第三個模板()在第二次轉換後執行,還是獨立工作複製? – rafter