以下是我的首发XML:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:something-well-formed">
<child1 attr1="a" attr2="b">
<child1 attr1="c" attr2="b"/>
</child1>
<child3/>
<child1 attr1="d" attr2="b">
<child2 attr1="e" attr2="b"/>
</child1>
</root>
在对上面的内容进行转换之后,我得到了一个中间结果xml,在这种情况下剥离了所有属性,从child1节点开始:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:something-well-formed">
<child1>
<child1/>
</child1>
<child3/>
<child1>
<child2 attr1="e" attr2="b"/>
</child1>
</root>
我想要做的是对上面生成的中间结果进行转换,以创建一个类似于下面示例的xml doc,在这种情况下,我可以指定第n个实例,在本例中, child1并相应地设置它的属性:
<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:something-well-formed">
<child1 attr1="something", attr2="something else">
<child1/>
</child1>
<child3/>
<child1>
<child2 attr1="e" attr2="b"/>
</child1>
</root>
这是我尝试使用的xslt示例:
<xsl:param name="element" />
<xsl:param name="attributes" />
<xsl:param name="nodeNumber"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="*[name(.)=$element]">
<xsl:copy>
<xsl:apply-templates select="@*" />
<!-- Splits into separate key/value pairs elements -->
<xsl:variable name="attributesSeq" select="tokenize($attributes, ';')" />
<xsl:for-each select="$attributesSeq">
<xsl:variable name="attributesSeq" select="tokenize(., ',')" />
<xsl:variable name="key"
select="replace($attributesSeq[1], '"', '')" />
<xsl:variable name="value"
select="replace($attributesSeq[2], '"', '')" />
<xsl:attribute name="{$key}">
<xsl:value-of select="$value" />
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates select="node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
问题是上面的xslt复制&#34;属性&#34;参数到child1的每个实例,当我的目标是复制&#34;属性&#34;的内容时参数到child1的第n个实例。
其他问题:我希望参数化节点名称是我选择传入的任何节点名称的第n个实例。上面的示例使用child1,但它应该适用于任何节点名称(即child3, child37等。
感谢您的帮助!
答案 0 :(得分:2)
嗯。如果你限制你的孩子&#34;要成为根节点的第N个孩子,其名称由element
给出,您可以使用您的方法,但您必须更换
<xsl:template match="*[name() = $element]">
通过
<xsl:template match="*[name() = $element][$nodeNumber]">
这对我有用(虽然xsltproc
不接受语法,但我不得不使用Saxon)。但是,如果您希望定位名称由element
提供的孩子的第N个后代实例,则它将无效。这将更棘手。我还没有找到答案。
答案 1 :(得分:1)
假设您收到此<xsl:param>
中的号码:
<xsl:param name="nodeNumber" select='2'/>
您可以在模板中添加谓词,并将变量作为参数传递:
<xsl:template match="*[name(.)=$element][$nodeNumber]">
....
</xsl:template>
这将根据元素在调用它的上下文中的位置来限制元素。
您还有一个元素名称的参数。如果您使用:
<xsl:param name="element" select="'child1'" />
它会在child1
上添加属性。如果您将其替换为'child3'
或'child2'
,则会相应地替换它们。 (显然,child3
和child2
在您的示例中$nodeNumber
必须为1,因为每个只有一个。)