xslt set node value in parent group
Sample XML input file:
<sample>
<vars>
<var>
<name>connection1</name>
<value>tcp</value>
</var>
<var>
<name>connection2</name>
<value>ssl</value&g开发者_C百科t;
</var>
</vars>
</sample>
Having looked at other questions answered, i have not seen an example that i am able to use. I wish to process the above xml file to edit a node value depending on the name node.
e.g. find name=connection1 and set the value that is in the same group to SSL
Output
<sample>
<vars>
<var>
<name>connection1</name>
<value>ssl</value>
</var>
<var>
<name>connection2</name>
<value>ssl</value>
</var>
</vars>
</sample>
Probably the shortest solution is this:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match=
"var[name='connection1']/value/text()">ssl</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document:
<sample>
<vars>
<var>
<name>connection1</name>
<value>tcp</value>
</var>
<var>
<name>connection2</name>
<value>ssl</value>
</var>
</vars>
</sample>
the wanted, correct result is produced:
<sample>
<vars>
<var>
<name>connection1</name>
<value>ssl</value>
</var>
<var>
<name>connection2</name>
<value>ssl</value>
</var>
</vars>
</sample>
Explanation:
This solution uses the most fundamental XSLT design pattern: the use of the identity rule to copy every node as-is and its overriding by a template matching a specific node that only needs to be changed.
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="var[name = 'connection1']/value">
<xsl:copy>
<xsl:text>ssl</xsl:text>
</xsl:copy>
</xsl:template>
You can use the following 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="value[preceding-sibling::name = 'connection1']">
<value>ssl</value>
</xsl:template>
</xsl:stylesheet>
Use an XSL Identity Transform along with a template that processes your specific case and substitutes ssl for tcp.
精彩评论