Creating an XML element at a specifc point using x

2019-08-20 07:57发布

I'm using XSLT to transform XML that I'm receiving from a webservice. What I've got is something like this:

<benefit>
   <statusReasonCode1>Code</statusReasonCode1>
   <statusReason1>Reason</statusReason1>
   <otherStuff1>blah</otherStuff1>
   <otherStuff2>blah</otherStuff2>
</benefit>

What I want is this:

<benefit>
   <statusReasonCode1>Code</statusReasonCode1>
   <statusReason1>Reason</statusReason1>
   <statusReasonText1>Code - Reason></statusReasonText1>
   <otherStuff1>blah</otherStuff1>
   <otherStuff2>blah</otherStuff2>
</benefit>

What I'm getting is this:

<benefit>
   <statusReasonCode1>Code</statusReasonCode1>
   <statusReason1>Reason</statusReason1>
   <otherStuff1>blah</otherStuff1>
   <otherStuff2>blah</otherStuff2>
   <statusReasonText1>Code - Reason></statusReasonText1>
</benefit>

This is the xslt that's doing it:

<xsl:template match=''benefit''>
    <xsl:copy use-attribute-sets=''newBenefit''>
        <xsl:apply-templates/>
        <statusReasonCodeText1><xsl:value-of select="statusReasonCode1"/><xsl:text> - </xsl:text><xsl:value-of select="statusReason1"/></statusReasonCodeText1> 
    </xsl:copy>  
</xsl:template>

Is there a way that I can specify location when creating an element?

标签: xml xslt
2条回答
神经病院院长
2楼-- · 2019-08-20 08:12

If the new element always has to be inserted after statusReason1 then you could do:

<xsl:template match="statusReason1">
  <xsl:copy-of select="."/>
  <statusReasonCodeText1><xsl:value-of select="../statusReasonCode1"/><xsl:text> - </xsl:text><xsl:value-of select="."/></statusReasonCodeText1>
</xsl:template>
查看更多
做自己的国王
3楼-- · 2019-08-20 08:20

You could do:

<xsl:template match="benefit">
    <xsl:copy>
        <xsl:apply-templates select="statusReasonCode1 | statusReason1"/>
        <statusReasonCodeText1>
            <xsl:value-of select="statusReasonCode1"/>
            <xsl:text> - </xsl:text>
            <xsl:value-of select="statusReason1"/>
        </statusReasonCodeText1>
        <xsl:apply-templates select="otherStuff1 | otherStuff2"/>
    </xsl:copy>
</xsl:template>

There are other ways depending on what you know about your input, as well as which version of XSLT you're using.


Added:

In the real-life case of this the other fields are numerous and dynamic, so I can't really add them each back by name

You can add them using:

<xsl:apply-templates select="*[not(self::statusReasonCode1 or self::statusReason1)]"/>

or:

<xsl:apply-templates select="*[not(starts-with(name(), 'statusReason'))]"/>
查看更多
登录 后发表回答