作为输入xml示例我有
<Elem1>
<Obj name="1">
<Obj name="2">
<Obj name="3">
</Elem1>
使用xslt规则我想获得类似下面的内容
<Elem1>
<Obj1 name="1">
<Obj2 name="2">
<Obj3 name="3">
</Elem1>
基本上,如果子元素的名称相同,我想在名称后追加第一个属性的名称。
我发现很多例子可以匹配,但只有当你知道元素的名称时才会这样。 有没有办法在不事先知道元素名称的情况下匹配这种情况 例如:
<Elem1>
<Second name="1">
<Second name="2">
<Second name="3">
</Elem1>
也将返回
<Elem1>
<Second1 name="1">
<Second2 name="2">
<Second3 name="3">
</Elem1>
先谢谢你的帮助。
答案 0 :(得分:3)
试试这个
<xsl:template match="*[@name][count(../*[name() = current()/name()]) > 1]">
<xsl:element name="{name()}{@name}">
<xsl:apply-templates select="node()|@*"/>
</xsl:element>
</xsl:template>
复制其他数据时使用身份转换为
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
答案 1 :(得分:3)
使用XSLT 2或3中的密钥完善Rupesh的精细答案你可以使用
<xsl:key name="group-by-name" match="*[@name]" use="node-name(.)"/>
<xsl:template match="*[@name and key('group-by-name', node-name(.), ..)[2]]">
<xsl:element name="{name()}{@name}" namespace="{namespace-uri()}">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
https://xsltfiddle.liberty-development.net/eiZQaF4/1
虽然考虑它的时间稍长,如果有一个元素有子孙,或者与key
函数的第三个参数同名的后代只允许限制,它可以给出不同于已接受答案的结果。搜索到子树但不到某个子树级别。
答案 2 :(得分:2)
Rupesh_Kr答案非常笼统,适用于任何情况。
但是,如果您想使用特定的xpath
,您只想根据规则更改节点,那么您可以使用以下stylesheet
<强> INPUT:强>
<?xml version="1.0"?>
<Elems>
<Elem>
<Obj1 name="1"/>
<Obj2 name="2"/>
<Obj3 name="3"/>
</Elem>
<Elem>
<Second name="1"/>
<Second name="2"/>
<Second name="3"/>
</Elem>
</Elems>
<强>样式表:强>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:redirect="http://xml.apache.org/xalan/redirect" xmlns:xalan="http://xml.apache.org/xslt" version="1.0" extension-element-prefixes="redirect">
<xsl:output method="xml" indent="yes" xalan:indent-amount="4"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/Elems/Elem"> <!-- only for those nodes you do a specific process -->
<!-- variable to store the name of the first child -->
<xsl:variable name="subNodeName" select="local-name(./*[1])"/>
<!-- variable to store the number of children -->
<xsl:variable name="countNodes" select="count(./*)"/>
<xsl:choose>
<xsl:when test="$countNodes=count(./*[local-name()=$subNodeName])"><!--when all children have the same name -->
<Elem>
<xsl:for-each select="./*">
<xsl:element name="{name()}{@name}">
<xsl:apply-templates select="node() | @*"/>
</xsl:element>
</xsl:for-each>
</Elem>
</xsl:when>
<xsl:otherwise>
<Elem>
<xsl:apply-templates select="node() | @*"/>
</Elem>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
<强>输出:强>
<?xml version="1.0"?>
<Elems>
<Elem>
<Obj1 name="1"/>
<Obj2 name="2"/>
<Obj3 name="3"/>
</Elem>
<Elem>
<Second1 name="1"/>
<Second2 name="2"/>
<Second3 name="3"/>
</Elem>
</Elems>
答案 3 :(得分:0)
warning
您也可以使用此xslt