开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜