2011-12-20 110 views
1

我有一些源XML包含由樣式錶轉換爲具有相同名稱的輸出元素的不同元素。輸出元素然後在每個元素上都需要一個'index'元素。 我的第一個選擇是使用position(),但當然只適用於它們所在的xsl:for-each的上下文。基於輸出而不是輸入的XSLT索引

這裏是一個示例XML:

<Root> 
    <TypeA Val="First Value"/> 
    <TypeA Val="Second Value"/> 
    <NotToBeTransformed Val="ignoreme"/> 
    <TypeB Val="Third Value"/> 
    <TypeB Val="Fourth Value"/> 
</Root> 

這裏是我怎麼想它呈現爲輸出:

<Output> 
    <Destination> 
     <Index>1</Index> 
     <Content>First Value</Content> 
    </Destination> 
    <Destination> 
     <Index>2</Index> 
     <Content>Second Value</Content> 
    </Destination> 
    <Destination> 
     <Index>3</Index> 
     <Content>Third Value</Content> 
    </Destination> 
    <Destination> 
     <Index>4</Index> 
     <Content>Fourth Value</Content> 
    </Destination> 
</Output> 

我簡單的XSLT如下:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"> 
<xsl:template match="/"> 
    <Output> 
     <xsl:for-each select="//TypeA"> 
      <Destination> 
       <Index><xsl:value-of select="position()"/></Index> 
       <Content><xsl:value-of select="@Val"/></Content> 
      </Destination> 
     </xsl:for-each> 
     <xsl:for-each select="//TypeB"> 
      <Destination> 
       <Index><xsl:value-of select="position()"/></Index> 
       <Content><xsl:value-of select="@Val"/></Content> 
      </Destination> 
     </xsl:for-each> 
    </Output> 
</xsl:template> 

B ut爲每個源元素集合輸出索引值爲1和2。 這可以在XSLT中完成,還是需要再次處理?我正在用C#代碼進行轉換,因此我可以運行初始轉換,然後在代碼中設置索引值。

任何幫助將被最感激地接受!

回答

2

根本不需要使用xsl:for-each(儘量避免它),既不需要單獨處理TypeATypeB元素。

這種轉變

<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="/*"> 
    <Output> 
    <xsl:apply-templates select="TypeA|TypeB"/> 
    </Output> 
</xsl:template> 
<xsl:template match="*/*"> 
    <Destination> 
     <Index><xsl:value-of select="position()"/></Index> 
     <Content><xsl:value-of select="@Val"/></Content> 
    </Destination> 
</xsl:template> 
</xsl:stylesheet> 

時所提供的XML文檔應用:

<Root> 
    <TypeA Val="First Value"/> 
    <TypeA Val="Second Value"/> 
    <NotToBeTransformed Val="ignoreme"/> 
    <TypeB Val="Third Value"/> 
    <TypeB Val="Fourth Value"/> 
</Root> 

產生想要的,正確的結果

<Output> 
    <Destination> 
     <Index>1</Index> 
     <Content>First Value</Content> 
    </Destination> 
    <Destination> 
     <Index>2</Index> 
     <Content>Second Value</Content> 
    </Destination> 
    <Destination> 
     <Index>3</Index> 
     <Content>Third Value</Content> 
    </Destination> 
    <Destination> 
     <Index>4</Index> 
     <Content>Fourth Value</Content> 
    </Destination> 
</Output> 
+0

對於我的示例XML來說,這是一個非常有效的答案,但是我想也許我讓我的示例太簡單了! 我想要轉換成索引輸出的元素有很多種不同的情況,並且埋入了許多其他元素中,所以使用'match =「*/*」'不幸的是我不是一個有效的解決方案。 – 2011-12-20 16:06:07

+0

思考你的答案 - 我可以分別爲我想要的元素(以類似於你的方式)調用相同的模板,並在其中使用'position()'函數嗎? – 2011-12-20 16:09:29

+0

@MathJones:在這種情況下,最合適的是用更真實的數據編輯/更新問題。請。 – 2011-12-20 16:12:51