Xml 使用XSLT迭代属性值
我有一个XML结构,比如Xml 使用XSLT迭代属性值,xml,xslt,xpath,Xml,Xslt,Xpath,我有一个XML结构,比如 <Object id="id0000" link="id0010 id0020"> <Data id="id1000"> <DataValue name="Obj0000"/> </Data> </Object> 我有几个“对象”节点,其中一些有一个链接,一些有两个或更多链接。链接(ID)之间用空格分隔。我已经使用了'tokenize()'-函数来获取各个链接ID <xs
<Object id="id0000" link="id0010 id0020">
<Data id="id1000">
<DataValue name="Obj0000"/>
</Data>
</Object>
我有几个“对象”节点,其中一些有一个链接,一些有两个或更多链接。链接(ID)之间用空格分隔。我已经使用了'tokenize()'-函数来获取各个链接ID
<xsl:variable name="links">
<xsl:value-of select="tokenize(@link, ' ')"/>
</xsl:variable>
每个链接都引用另一个包含一些数据的“对象”
现在我想使用链接(ID)的位置作为字符串,因此我的输出应该类似于
<Object>
<hasName>Obj0000</hasName>
<hasStartLink>id0010</hasStartLink>
</Object>
<LinkedObject>
<hasID>id0010</hasID>
<hasDescription>1. link of Obj0000</hasDescription>
<hasNextLink>id0020</hasNextLink>
</LinkedObject>
<LinkedObject>
<hasID>id0020</hasID>
<hasDescription>2. link of Obj0000</hasDescription>
</LinkedObject>
<!-- inside another template -->
<xsl:call-template name="LinkedObj">
<xsl:with-param name="count" select="1"/>
</xsl:call-template>
<!-- end of another template -->
<xsl:template name="LinkedObj">
<xsl:param name="count"/>
<!-- do some stuff here -->
<!-- use '$count' as position -->
<xsl:call-template name="LinkedObj>
<xsl:with-param name="count" select="$count + 1"/>
</xsl:call-template>
</xsl:template>
Obj0000
id0010
id0010
1.Obj0000的链接
id0020
id0020
2.Obj0000的链接
我发现很多页面都说,迭代和保存当前位置是无法用这种方式完成的,必须以某种方式解决。我找到了类似的东西
<Object>
<hasName>Obj0000</hasName>
<hasStartLink>id0010</hasStartLink>
</Object>
<LinkedObject>
<hasID>id0010</hasID>
<hasDescription>1. link of Obj0000</hasDescription>
<hasNextLink>id0020</hasNextLink>
</LinkedObject>
<LinkedObject>
<hasID>id0020</hasID>
<hasDescription>2. link of Obj0000</hasDescription>
</LinkedObject>
<!-- inside another template -->
<xsl:call-template name="LinkedObj">
<xsl:with-param name="count" select="1"/>
</xsl:call-template>
<!-- end of another template -->
<xsl:template name="LinkedObj">
<xsl:param name="count"/>
<!-- do some stuff here -->
<!-- use '$count' as position -->
<xsl:call-template name="LinkedObj>
<xsl:with-param name="count" select="$count + 1"/>
</xsl:call-template>
</xsl:template>
假设您有多个对象,我在源文件中添加了一个根元素:
<?xml version="1.0" encoding="UTF-8"?>
<Objects>
<Object id="id0000" link="id0010 id0020">
<Data id="id1000">
<DataValue name="Obj0000"/>
</Data>
</Object>
</Objects>
您不必对LinkedObj模板使用递归调用,只需迭代链接并在循环中调用:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" version="2.0">
<xsl:output indent="yes"/>
<xsl:template match="Objects">
<Objects>
<xsl:apply-templates select="Object"/>
</Objects>
</xsl:template>
<xsl:template match="Object">
<xsl:variable name="name" select="Data/DataValue/@name"/>
<xsl:variable name="links" select="tokenize(@link, ' ')"/>
<xsl:element name="Object">
<xsl:element name="hasName">
<xsl:value-of select="$name"/>
</xsl:element>
<xsl:element name="hasStartLink">
<xsl:value-of select="$links[1]"/>
</xsl:element>
</xsl:element>
<xsl:for-each select="$links">
<xsl:variable name="position" select="position()"/>
<xsl:call-template name="LinkedObj">
<xsl:with-param name="position" select="$position"/>
<xsl:with-param name="id" select="."/>
<xsl:with-param name="nextLink" select="$links[$position + 1]"/>
<xsl:with-param name="objectName" select="$name"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="LinkedObj">
<xsl:param name="position"/>
<xsl:param name="id"/>
<xsl:param name="nextLink"/>
<xsl:param name="objectName"/>
<LinkedObject>
<hasID>
<xsl:value-of select="$id"/>
</hasID>
<hasDescription>
<xsl:value-of select="position()"/>
<xsl:text>. link of </xsl:text>
<xsl:value-of select="$objectName"/>
</hasDescription>
<xsl:if test="$nextLink!=''">
<hasNextLink>
<xsl:value-of select="$nextLink"/>
</hasNextLink>
</xsl:if>
</LinkedObject>
</xsl:template>
</xsl:stylesheet>
. 链接
结果:
<?xml version="1.0" encoding="UTF-8"?>
<Objects>
<Object>
<hasName>Obj0000</hasName>
<hasStartLink>id0010</hasStartLink>
</Object>
<LinkedObject>
<hasID>id0010</hasID>
<hasDescription>1. link of Obj0000</hasDescription>
<hasNextLink>id0020</hasNextLink>
</LinkedObject>
<LinkedObject>
<hasID>id0020</hasID>
<hasDescription>2. link of Obj0000</hasDescription>
</LinkedObject>
</Objects>
Obj0000
id0010
id0010
1.Obj0000的链接
id0020
id0020
2.Obj0000的链接
尽管这是所需的输出结构,但不确定这是否正确,我猜测LinkedObjects应该在每个对象中,但是这种更改很小…正如我现在所做的(如上所述)使用“调用模板”而不是“应用模板”,我的上下文不会改变,因此现在我可以在调用模板中编写
。在调用的模板中,我现在可以编写
。该位置将始终获得当前链接,因为它在此模板中递增。我添加了一个答案,作为旁注,不要在变量中使用
,这将再次提供相同的字符串,可以使用xsl:sequence
或使用变量的select属性。我当前在调用“LinkedObj”模板。在此模板中,我使用参数“position”(将递增)来获取标记化字符串的内容,如$links[$position]
。因此,我可能没有理解全部要点:我存储在参数“link”中的标记化字符串基本上只是一个字符串(分成一系列子字符串).每次调用“LinkedObj”时,我都希望访问不同的子字符串“模板。我尝试使用你的想法,直到我意识到我必须传递每个属性和节点,我想稍后将其作为参数处理,因为模板是用字符串而不是节点调用的。我已经按照我的方式工作了,但是现在我想知道是否值得努力改变我的代码来使用你的想法。我认为这与“完成这样一项任务的常见方式”有关,我不知道常见方式。