Xml XSLT拷贝&;设置属性值
下面是我的起始XML:Xml XSLT拷贝&;设置属性值,xml,xslt,Xml,Xslt,下面是我的起始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">
<?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的第n个实例,并相应地设置它的属性:
<?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 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>
<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>
假设您收到此
中的号码:
您可以向模板添加谓词,将变量作为参数传递:
<xsl:template match="*[name(.)=$element][$nodeNumber]">
....
</xsl:template>
....
这将根据元素在调用它的上下文中的位置来限制元素
您还有一个用于元素名称的参数。如果您使用:
<xsl:param name="element" select="'child1'" />
它将在child1
上添加属性。如果将其替换为'child3'
或'child2'
,它将相应地替换它们。(显然,对于示例中的child3
和child2
,$nodeNumber
必须为1,因为每个都只有一个。)Hmmm。如果将“child”限制为根节点的第N个子节点,其名称由元素给出,则可以完全使用您的方法,但必须替换
<xsl:template match="*[name() = $element]">
借
这对我很有用(虽然xsltproc
不接受语法,但我不得不使用Saxon)。但是,如果您希望以子对象的第N个后代实例为目标,该子对象的名称由元素给出,则该子对象将不起作用。这将更加棘手。我还没有找到答案。xsltproc拒绝它的原因是因为它不是有效的XSLT 1.0-规范的1.0版禁止在match
表达式中引用变量,2.0版允许它们。感谢您的提示!1.0和2.0之间还有一个细微的差别::-)我从XSLT1.0.Yep中不存在的tokenize()
和replace()
函数猜到是XSLT2.0。那也是真的<但是,code>xsltproc
并没有对这些问题进行太多的抱怨。
<xsl:template match="*[name() = $element]">
<xsl:template match="*[name() = $element][$nodeNumber]">