2013-07-24 79 views
1

我有下面的XML中,XML具有「項目」元素的多次數,並且會有「信息」元素的單次數XSLT添加嵌套元素基於現有元素的最後一個節點

<?xml version="1.0" encoding="utf-8" ?> 

<root xmlns="http://temo.com/tempe.xsd"> 


<di>  
<md>2013-07-09T09:43:00</md> 
</di> 


<list> 

<item> 
<Name>test</Name> 
<section block1="true"> 
<block1> 
<move>1</move> 
<info> 
<item1>test item 1</item1> 
<item2>false</item2> 
<item3>1</item3> 
</info> 
</block1> 
<block2> 
... 
</block2> 
</section> 
</item> 
</list> 

<option> 
... 
</option> 

</root> 

,我想將其轉換爲下面的格式,也就是說,如果「移動」元素存在,那麼在「信息」元素的最後位置應創建

<item4> 
<item5>1</item5> 
</item4> 


<?xml version="1.0" encoding="utf-8" ?> 

<root xmlns="http://temo.com/tempe.xsd"> 


<di>  
<md>2013-07-09T09:43:00</md> 
</di> 


<list> 

<item> 
<Name>test</Name> 
<section block1="true"> 
<block1> 
<move>1</move> 
<info> 
    <item1>test item 1</item1> 
    <item2>false</item2> 
    <item3>1</item3> 
    <item4> 
    <item5>1</item5> 
    </item4> 
</info> 
</block1> 
    <block2> 
    ... 
    </block2> 
</section> 
</item> 
<item> 
    ... 
</item> 
</list> 
<option> 
... 
</option> 

</root> 

我使用下面的XSLT添加新元素轉換爲上述格式

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" 
> 
<xsl:output method="xml" indent="yes" encoding="utf-8"/> 

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

<xsl:template match="/info/*[position()=last()]"> 
<xsl:copy> 
<xsl:choose> 
<xsl:when test="/section/block/move"> 
<!--Add new element item4--> 
<xsl:element name="item4"> 
<xsl:element name="item5"> 
<xsl:value-of select="section/block/move"/> 
</xsl:element> 
</xsl:element> 
</xsl:when> 
<xsl:otherwise> 
<xsl:call-template name="identity" /> 
</xsl:otherwise> 
</xsl:choose> 
</xsl:copy> 
</xsl:template> 
</xsl:stylesheet> 

您能否請幫助我在XSLT中找到問題? 我是新來的XSLT

謝謝:)

回答

0

您對XML輸入一個默認命名空間聲明和輸出XML也需要,所以你需要

的xmlns是要插入命名空間的元素:tp =「http://temo.com/tempe.xsd」

在您的xsl:stylesheet根元素上,那麼您需要調整您的路徑和模式以使用該前綴,例如而不是info你需要tp:info而不是section/block/move你需要tp:section/tp:block/tp:move等等。

您的XSLT樣本中的路徑似乎不對,但是你使用/section/block/move但你的根元素是root所以/section永遠不會選擇任何內容,即使你加命名空間前綴。而你的路徑有block,輸入有block1

,而不是試圖解決您的代碼,我寫了一個新的樣式表,它是

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns="http://temo.com/tempe.xsd" 
    xmlns:tp="http://temo.com/tempe.xsd" 
    exclude-result-prefixes="tp" 
    version="1.0"> 

<xsl:param name="to-insert" xml:space="preserve"> 
<item4> 
<item5><xsl:value-of select="//tp:section/tp:block1/tp:move"/></item5> 
</item4> 
</xsl:param> 

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

<xsl:template match="tp:item[.//tp:move[. = 1]]//tp:info"> 
    <xsl:copy> 
    <xsl:apply-templates select="@* | node()"/> 
    <xsl:copy-of select="$to-insert"/> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

它輸出

<root xmlns="http://temo.com/tempe.xsd"> 


<di> 
<md>2013-07-09T09:43:00</md> 
</di> 


<list> 

<item> 
<Name>test</Name> 
<section block1="true"> 
<block1> 
<move>1</move> 
<info> 
<item1>test item 1</item1> 
<item2>false</item2> 
<item3>1</item3> 

<item4 xmlns:tp="http://temo.com/tempe.xsd"> 
<item5>1</item5> 
</item4> 
</info> 
</block1> 
<block2> 
... 
</block2> 
</section> 
</item> 
</list> 

<option> 
... 
</option> 

</root> 
+0

非常感謝!這是真棒:) – user2615051

+0

我有一個問題,我已將模板匹配更改爲「pc:Signal [.// pc:StationSetReference [。= number()]] // pc:Data」,因爲「move」元素可以具有任何數值。參數 - $ to-insert總是返回移動元素的第一個匹配值。是否有可能獲得當前的「移動」元素值。 – user2615051

+0

是的,而不是''把元素直接放在那裏。 ''。 –