我需要采用" a"的属性。标记和处理它们。
来源:
<Data>
<AAA>
<strong xmlns="http://www.w3.org/1999/xhtml">some Text
<a href="#" name="Value1,Value2,Value3,Value4,Value5,Value6" id="Functionaldata" xmlns="http://www.w3.org/1999/xhtml">Value6</a>
</strong>
hello
<a title="google" href="http://google.com" xmlns="http://www.w3.org/1999/xhtml">Hey</a> all <a href="#" name="element1,element2,element3,element4,element5,element6" id="Functionaldata" xmlns="http://www.w3.org/1999/xhtml">element6</a>
<AAA>
</Data>
输出
<Content>
<Information>
<text>
<strong xmlns="http://www.w3.org/1999/xhtml">some Text
<dynamicinfo type="Value1" name="Value2" group="Value3" id="Value4" link="Value5" display="Value6"/>
</strong>
hello<a title="google" href="http://google.com">Hey</a> all
<dynamicinfo type="element1" name="element2" group="element3" id="element4" link="element5" display="element6"/>
</text>
</Information>
</Content>
我对处理&#34; a&#34;标签id = Functionaldata。
可以帮助他们发表意见。
谢谢。
答案 0 :(得分:1)
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://www.w3.org/1999/xhtml"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:names>
<n>type</n>
<n>name</n>
<n>group</n>
<n>id</n>
<n>link</n>
<n>display</n>
</my:names>
<xsl:variable name="vNames" select="document('')/*/my:names/*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a[@name] | x:a[@name]">
<xsl:copy>
<xsl:apply-templates select="@*[not(name()='name')]"/>
<xsl:apply-templates select="@name"/>
</xsl:copy>
</xsl:template>
<xsl:template match="a/@name | x:a/@name" name="split">
<xsl:param name="pText" select="."/>
<xsl:param name="pOrd" select="1"/>
<xsl:if test="$pText">
<xsl:attribute name="{$vNames[position()=$pOrd]}">
<xsl:value-of select=
"substring-before(concat($pText, ','), ',')"/>
</xsl:attribute>
<xsl:call-template name="split">
<xsl:with-param name="pText" select="substring-after($pText, ',')"/>
<xsl:with-param name="pOrd" select="$pOrd+1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档时:
<Data>
<AAA>
<strong xmlns="http://www.w3.org/1999/xhtml">some Text
<a href="#" name="Value1,Value2,Value3,Value4,Value5,Value6" id="Functionaldata">Value6</a>
</strong>
hello
<a title="google" href="http://google.com">Hey</a> all
<a href="#" name="element1,element2,element3,element4,element5,element6" id="Functionaldata">element6</a>
</AAA>
</Data>
会产生想要的正确结果:
<Data>
<AAA>
<strong xmlns="http://www.w3.org/1999/xhtml">some Text
<a href="#" id="Value4" type="Value1" name="Value2" group="Value3" link="Value5" display="Value6"/>
</strong>
hello
<a title="google" href="http://google.com">Hey</a> all
<a href="#" id="element4" type="element1" name="element2" group="element3" link="element5" display="element6"/>
</AAA>
</Data>
<强>解释强>:
这是基于您之前问题的解决方案,并进行了以下更改:
使用和覆盖身份规则。
而不是元素,创建的属性具有拆分结果的值。
要生成的属性的名称被指定为全局my:names
元素的子项。
<强>更新强>:
OP在评论中修改了他的问题,说:
我忘了为“a”标签添加名称空间。所有“a”标签都有 “xhtml”命名空间。
答案是,在这种情况下,提供的转换仍然正常,并且不需要对其进行任何更改。
但是,可以通过以下方式简化 :
<强>替换强>:
<xsl:template match="a[@name] | x:a[@name]">
只需:
<xsl:template match="x:a[@name]">
并替换:
<xsl:template match="a/@name | x:a/@name" name="split">
只需:
<xsl:template match="x:a/@name" name="split">
这些更改后的完整转换变为:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://www.w3.org/1999/xhtml"
xmlns:my="my:my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:names>
<n>type</n>
<n>name</n>
<n>group</n>
<n>id</n>
<n>link</n>
<n>display</n>
</my:names>
<xsl:variable name="vNames" select="document('')/*/my:names/*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="x:a[@name]">
<xsl:copy>
<xsl:apply-templates select="@*[not(name()='name')]"/>
<xsl:apply-templates select="@name"/>
</xsl:copy>
</xsl:template>
<xsl:template match="x:a/@name" name="split">
<xsl:param name="pText" select="."/>
<xsl:param name="pOrd" select="1"/>
<xsl:if test="$pText">
<xsl:attribute name="{$vNames[position()=$pOrd]}">
<xsl:value-of select=
"substring-before(concat($pText, ','), ',')"/>
</xsl:attribute>
<xsl:call-template name="split">
<xsl:with-param name="pText" select="substring-after($pText, ',')"/>
<xsl:with-param name="pOrd" select="$pOrd+1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
如果您有权访问EXSLT,则可以使用str:split()
方法来实现此目的。
更大的问题是,如何将值映射到您给出的新属性名称?我想出了这个,它先声明了值名称,然后将值名称1映射到拆分值1,将值名称2映射到拆分值2等等。
<!-- node-set of value names, which will each correspond to the value at the same index, once they're split -->
<xsl:variable name='value_names' select='str:split("type|name|group|id|link|display", "|")' />
<!-- match root -->
<xsl:template match="/">
<dynamicdata>
<xsl:apply-templates name='values' select='str:split(root/a/@name, ",")' />
</dynamicdata>
</xsl:template>
<!-- iteration content - each value from the split -->
<xsl:template match='token'>
<xsl:variable name='pos' select='position()' />
<xsl:attribute name='{$value_names[$pos]}'><xsl:value-of select='.' /></xsl:attribute>
</xsl:template>
您可以在this XMLPlayground session看到这一点(请参阅输出源)。