我对XSLT很陌生并且有一个迫切的工作要求,我发现要解决这个问题非常复杂。
我有一个XML文档,需要在特定条件下添加属性。
XML文档非常简单:
<A x="foo" y="bar" z="">
<B/>
<C/></A>
基本上,如果存在属性“z”。然后需要将新属性添加到节点“A”。属性的值必须是在某些位置替换值为“x”和“y”的文本字符串。结果应如下所示:
<A x="foo" y="bar" z="" new="values present are x=foo and y=bar">
<B/>
<C/></A>
我已经创建了一个将文档复制到属性级别的XSLT。但是在尝试创建测试属性z的逻辑并创建基于x和y的字符串时,我遇到了绊脚石。
有人可以帮忙吗?
由于
另外 - 如果我的代码格式糟透了,请道歉
来自评论:
有些事情正在停止 这些解决方案有效文本XML 我上面实际上有一个根 包含所有内容的节点
<R>
。 R node有一个这样的属性:xmlns="http://www.fixprotocol.org/FIXML-4-4"
。 出于某种原因添加此属性 导致模板匹配“A” 不行吗?!
答案 0 :(得分:3)
已更新:OP已解释(仅在评论中注释!):
有些事情正在停止 这些解决方案有效文本XML 我上面实际上有一个根 包含它的节点。
<R>
node有一个这样的属性:xmlns="http://www.fixprotocol.org/FIXML-4-4"
。 出于某种原因添加此属性 导致模板匹配“A” 不行吗?!
这可能是最短的:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://www.fixprotocol.org/FIXML-4-4"
xmlns="http://www.fixprotocol.org/FIXML-4-4" exclude-result-prefixes="x">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="x:A[@z]">
<A new="values present are x={@x} and y={@y}">
<xsl:apply-templates select="node()|@*"/>
</A>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的XML文档:
<R xmlns="http://www.fixprotocol.org/FIXML-4-4">
<A x="foo" y="bar" z="">
<B/>
<C/>
</A>
</R>
产生了想要的正确结果:
<R xmlns="http://www.fixprotocol.org/FIXML-4-4">
<A new="values present are x=foo and y=bar" x="foo" y="bar" z="">
<B></B>
<C></C>
</A>
</R>
答案 1 :(得分:1)
您可以使用以下XSLT:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="A">
<A>
<xsl:if test="@z">
<xsl:attribute name="new">
<xsl:value-of select="concat('values present are x=',@x,' and y=',@y)"/>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="@* | node()"/>
</A>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:1)
编辑:现在使用正确的命名空间。
此样式表:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fixml="http://www.fixprotocol.org/FIXML-4-4">
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="fixml:A/@z">
<xsl:call-template name="identity"/>
<xsl:attribute name="new">
<xsl:value-of
select="concat('values present are x=',../@x,' and y=',../@y)"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
使用此输入:
<R xmlns="http://www.fixprotocol.org/FIXML-4-4">
<A x="foo" y="bar" z="">
<B/>
<C/>
</A>
</R>
输出:
<R xmlns="http://www.fixprotocol.org/FIXML-4-4">
<A x="foo" y="bar" z="" new="values present are x=foo and y=bar">
<B></B>
<C></C>
</A>
</R>