我有以下XML,XML有多个出现的'item'元素,并且会有单次出现的'info'元素
<?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>
我想将其转换为以下格式,即,如果存在"移动"元素,则应在"info"元素的最后一个位置添加新元素
<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 的新手
谢谢:)
您在输入 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>