2013-06-04 92 views
1

節點模板這是我的XML輸入文件XSL,只適用於兒童

<ELEMENTROOT> 
    <id>10036</id> 
    <firstName>Marco</firstName> 
    <lastName>Nato</lastName> 
    <addressSet> 
    <address> 
     <country> 
      <displayValue>France</displayValue> 
     </country> 
    </address> 
    </addressSet> 
    <clobMap/> 
    <dateMap> 
    <entry> 
     <key>birthDate</key> 
     <value>1973-11-29T00:00:00</value> 
    </entry> 
    </dateMap> 
    <myMap> 
     <entry> 
      <key>gender</key> 
      <value> 
       <id>1042</id> 
       <displayValue>Femminile</displayValue> 
      </value> 
     </entry> 
    <myMap> 
</ELEMENTROOT> 

結果我想獲得

<ELEMENTROOT> 
    <id>10036</id> 
    <firstName>Marco</firstName> 
    <lastName>Nato</lastName> 
    <addressSet> 
    <address> 
     <country> 
      <displayValue>France</displayValue> 
     </country> 
    </address> 
    </addressSet> 
    <clobMap/> <!-- Unlikely I don't have this with my xsl--> 
    <birthDate> 
     1973-11-29T00:00:00 
    </birthDate> 
    <gender> 
    <id>1042</id> 
    <displayValue>Femminile</displayValue> 
    </gender> 
</ELEMENTROOT> 

,我試圖XSL文件是這樣的:

<?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="myMap"> 
    <xsl:for-each select="entry"> 
     <xsl:element name="{key}"> 
      <xsl:copy-of select="value/*" /> 
     </xsl:element> 
     </xsl:for-each> 
    </xsl:template> 
    <xsl:template match="*[contains(name(), 'Map')][not(contains(name(), 'myMap'))]"> 
     <xsl:for-each select="./entry"> 
     <xsl:element name="{key}"> 
      <xsl:value-of select="value" /> 
     </xsl:element> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

正如你可以理解我有這個問題: 我必須應用只有模板,如果地圖有孩子否則我將失去上例中的節點。 我試過不同的方法來匹配只有有孩子的地圖,但我有兩種地圖:每個條目有兩個值的「myMap」和每個條目有一個值的「dateMap」。

非常感謝您的幫助!

回答

2

而不是做一個來查看名稱中是否有「Map」,檢查一個元素是否有entry/key。然後你可以「解開」value

實施例...

XML輸入

<ELEMENTROOT> 
    <id>10036</id> 
    <firstName>Marco</firstName> 
    <lastName>Nato</lastName> 
    <addressSet> 
     <address> 
     <country> 
      <displayValue>France</displayValue> 
     </country> 
    </address> 
    </addressSet> 
    <clobMap/> 
    <dateMap> 
     <entry> 
      <key>birthDate</key> 
      <value>1973-11-29T00:00:00</value> 
     </entry> 
    </dateMap> 
    <myMap> 
     <entry> 
      <key>gender</key> 
      <value> 
       <id>1042</id> 
       <displayValue>Femminile</displayValue> 
      </value> 
     </entry> 
    </myMap> 
</ELEMENTROOT> 

XSLT 1.0

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

    <!--Identity transform. Anything not matched by another template 
    will be output without change.--> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <!--Match any element that has an "entry" element that has a "key" 
    element.--> 
    <xsl:template match="*[entry/key]"> 
     <!--Don't output anything. Only apply-templates to the "key" element. 
      We don't need "entry" for anything.--> 
     <xsl:apply-templates select="entry/key"/> 
    </xsl:template> 

    <!--Match "key" element.--> 
    <xsl:template match="key"> 
     <!--Create a new element with the name based on the content 
     of "key".--> 
     <xsl:element name="{.}"> 
      <!--Inside of the newly created element apply-templates to 
      the following sibling "value" element.--> 
      <xsl:apply-templates select="following-sibling::value"/> 
     </xsl:element> 
    </xsl:template> 

    <!--Match "value" element.--> 
    <xsl:template match="value"> 
     <!--Don't output the "value" element itself. The apply-templates 
     will apply to any child node. The identity transform will handle 
     the child nodes. If the child is text(), it will output the text. 
     If the child/children are elements, it will output the elements.--> 
     <xsl:apply-templates/> 
    </xsl:template> 

</xsl:stylesheet> 

輸出

<ELEMENTROOT> 
    <id>10036</id> 
    <firstName>Marco</firstName> 
    <lastName>Nato</lastName> 
    <addressSet> 
     <address> 
     <country> 
      <displayValue>France</displayValue> 
     </country> 
     </address> 
    </addressSet> 
    <clobMap/> 
    <birthDate>1973-11-29T00:00:00</birthDate> 
    <gender> 
     <id>1042</id> 
     <displayValue>Femminile</displayValue> 
    </gender> 
</ELEMENTROOT> 
1

添加一個模板match="*[contains(name(), 'Map')] [not(self::myMap)] [not(*)]"並讓它處理無子女的地圖元素的情況。

+0

你能稍微詳細一點解釋標籤嗎? –

+0

你不明白表達的哪一部分?我很高興回答這些問題,表明您已經努力瞭解正在發生的事情。 –

+0

您寫的表達式匹配具有Map作爲單詞和'[not(self :: myMap)] [not(*)]''的標記嗎?你可以像丹尼爾海莉做的那樣向我展示你的解決方案嗎? –

相關問題