2012-05-25 96 views
2

我有一個看起來像這樣的XML文檔中確定上下文節點的位置:另一個節點集

<Root> 
    <Cover> 
     <Cover_Ref Val="1"/> 
     <Cover_Code Val="Food in transit"/> 
     <AdditionalCover> 
      <AdditionalCover_Area Val="Sussex"/> 
     </AdditionalCover> 
    </Cover> 
    <Cover> 
     <Cover_Ref Val="2"/> 
     <Cover_Code Val="Frozen goods"/> 
    </Cover> 
    <Cover> 
     <Cover_Ref Val="3"/> 
     <Cover_Code Val="Business equipment"/> 
     <AdditionalCover> 
      <AdditionalCover_Area Val="Sussex"/> 
     </AdditionalCover> 
    </Cover> 
    <AdditionalCoverResult> 
     <CoverArea Val="Sussex"/> 
     <CoverExcluded Val="N"/> 
    </AdditionalCoverResult> 
    <AdditionalCoverResult> 
     <CoverArea Val="Sussex"/> 
     <CoverExcluded Val="Y"/> 
    </AdditionalCoverResult> 
</Root> 

我需要把它改造成這樣的:

<Insurances> 
    <Insurance> 
     <reference>1</reference> 
     <CoverType>Food in transit</CoverType> 
     <Region>Sussex</Region> 
     <Excluded>N</Excluded> 
    </Insurance> 
    <Insurance> 
     <reference>2</reference> 
     <CoverType>Frozen goods</CoverType> 
    </Insurance> 
    <Insurance> 
     <reference>3</reference> 
     <CoverType>Business equipment</CoverType> 
     <Region>Sussex</Region> 
     <Excluded>Y</Excluded> 
    </Insurance> 
</Insurances> 

的AdditionalCoverResult元素指包含AdditionalCover元素的封面元素 - 因此第一個封面元素的封面不排除,而第三個封面元素的封面不包括在內。第二個封面元素沒有AdditionalCover,因此沒有引用它的AdditionalCoverResult元素。

我的問題是,在<xsl:for-each select="//Cover">循環內,我想不出一種方法來確定我應該尋找哪個AdditionalCoverResult元素。在每個結尾中使用position()與我不正確地輸出AdditionalCoverResult信息爲一個沒有AdditionalCover的封面元素。

我必須保留Cover的原始順序,所以我不能做兩個單獨的循環,一個用於CoverCover和另一個用於Cover without AdditionalCover。

在由//Cover返回的節點集內有沒有一種方法可以識別上下文節點在由//Cover[AdditionalCover]返回的節點集內的位置?

我有點猜測,對於Cover元素,我需要考慮「我在//Cover[AdditionalCover]內部有哪些索引,以便我可以使用該索引來標識我的對應AdditionalCoverResult元素?」

回答

1

這種轉變

<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="/*"> 
    <Insurances> 
    <xsl:apply-templates select="Cover"/> 
    </Insurances> 
</xsl:template> 

<xsl:template match="Cover"> 
    <Insurance> 
    <xsl:apply-templates/> 
    </Insurance> 
</xsl:template> 

<xsl:template match="Cover_Ref"> 
    <reference><xsl:value-of select="@Val"/></reference> 
</xsl:template> 

<xsl:template match="Cover_Code"> 
    <CoverType><xsl:value-of select="@Val"/></CoverType> 
</xsl:template> 

<xsl:template match="AdditionalCover_Area"> 
    <Region><xsl:value-of select="@Val"/></Region> 

    <Excluded> 
    <xsl:value-of select= 
    "/*/AdditionalCoverResult[CoverArea/@Val=current()/@Val] 
      [position() 
      = 
       1 +count(current() 
         /ancestor::Cover[1] 
          /preceding-sibling::Cover 
          [AdditionalCover 
           /AdditionalCover_Area/@Val 
          = 
          current()/@Val 
          ] 
        ) 
       ] 
       /CoverExcluded/@Val 
    "/> 
    </Excluded> 
</xsl:template> 
</xsl:stylesheet> 

時所提供的XML文檔應用:

<Root> 
    <Cover> 
     <Cover_Ref Val="1"/> 
     <Cover_Code Val="Food in transit"/> 
     <AdditionalCover> 
      <AdditionalCover_Area Val="Sussex"/> 
     </AdditionalCover> 
    </Cover> 
    <Cover> 
     <Cover_Ref Val="2"/> 
     <Cover_Code Val="Frozen goods"/> 
    </Cover> 
    <Cover> 
     <Cover_Ref Val="3"/> 
     <Cover_Code Val="Business equipment"/> 
     <AdditionalCover> 
      <AdditionalCover_Area Val="Sussex"/> 
     </AdditionalCover> 
    </Cover> 
    <AdditionalCoverResult> 
     <CoverArea Val="Sussex"/> 
     <CoverExcluded Val="N"/> 
    </AdditionalCoverResult> 
    <AdditionalCoverResult> 
     <CoverArea Val="Sussex"/> 
     <CoverExcluded Val="Y"/> 
    </AdditionalCoverResult> 
</Root> 

產生想要的,正確的結果

<Insurances> 
    <Insurance> 
     <reference>1</reference> 
     <CoverType>Food in transit</CoverType> 
     <Region>Sussex</Region> 
     <Excluded>N</Excluded> 
    </Insurance> 
    <Insurance> 
     <reference>2</reference> 
     <CoverType>Frozen goods</CoverType> 
    </Insurance> 
    <Insurance> 
     <reference>3</reference> 
     <CoverType>Business equipment</CoverType> 
     <Region>Sussex</Region> 
     <Excluded>Y</Excluded> 
    </Insurance> 
</Insurances> 
0

你可以保存當前的環境下,你有興趣在一個變量的一部分 - 所以像:

+0

嗨,尼克,我遇到的問題是,兩個封面元素與CoverCover的CoverArea值是相同的 - 他們都是「蘇塞克斯」。這就是爲什麼我不得不嘗試在另一個節點集內找到我的上下文節點的索引。 –

0

張貼的問題後,我看到了相關部分的鏈接 - xpath/xslt to determine index of context node relative to all nodes of same name?

Dimitre Novatchev的回答說,通過使用

count(preceding::question)+1 

你可以找到當前上下文節點的指數相對於所有question文檔中的元素。

對於我的問題,我使用count(preceding::Cover[AdditionalCover])+1,它的工作原理 - 我希望我已經正確理解它,但它似乎確實有用。

我不會立即選擇這個作爲正確答案,因爲如果任何人有任何其他方式來做到這一點,我會非常感興趣 - 我可能是XSLT的中級水平,這是一個學習更多關於它!

+0

你幾乎就在那裏 - 你現有的解決方案不適用於一般情況下,可能有多個不同區域具有不同的覆蓋範圍。您可能有興趣查看完整且正確的解決方案。 –

+0

輝煌,非常感謝Dimitre! –

+0

馬特瓊斯:不客氣。 –

相關問題