2013-07-24 82 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

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