0
votes

I have the following xml

 <?xml version="1.0" encoding="UTF-8"?>
<typeNames xmlns="http://www.dsttechnologies.com/awd/rest/v1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <typeName recordType="case" href="awdServer/awd/services/v1/businessareas/SAMPLEBA/types/SAMPLECASE">SAMPLECASE</typeName>
   <typeName recordType="folder" href="awdServer/awd/services/v1/businessareas/SAMPLEBA/types/SAMPLEFLD">SAMPLEFLD</typeName>
   <typeName recordType="source" href="awdServer/awd/services/v1/businessareas/SAMPLEBA/types/SAMPLEST">SAMPLEST</typeName>
   <typeName recordType="transaction" href="awdServer/awd/services/v1/businessareas/SAMPLEBA/types/SAMPLEWT">SAMPLEWT</typeName>
</typeNames>

I want to transform above xml as below by using XSLT:

 <response>
         <results>

               <source>
                  SAMPLEST
               </source>

         </results>
      </response>
   </xsl:template>

I just want to get the source from the input xml to the output xml.

I am trying with the following xml, but couldn't get the required output xml:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:v="http://www.dsttechnologies.com/awd/rest/v1" version="2.0" exclude-result-prefixes="v">
   <xsl:output method="xml" version="1.0" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
   <xsl:strip-space elements="*" />
   <!-- identity transform -->
   <xsl:template match="@*|node()">
      <xsl:copy>
         <xsl:apply-templates select="@*|node()" />
      </xsl:copy>
   </xsl:template>
   <xsl:template match="typeNames">
      <response>
         <results>

               <source>
                  <xsl:value-of select="source" />
               </source>

         </results>
      </response>
   </xsl:template>
</xsl:stylesheet>
1
You have declared a prefix, but you are not using it. And there is no source element in your input XMLmichael.hor257k

1 Answers

2
votes

I. Namespace in input xml

<typeNames xmlns="http://www.dsttechnologies.com/awd/rest/v1"...

xmlns puts self + all child nodes into a namespace. This namespace does not need any prefix.

II. Namespace in XSLT

... xmlns:v="http://www.dsttechnologies.com/awd/rest/v1"...

You prefixed the namespace (same uri as source) with v, so you have to write this prefix in your xpath as well.

<xsl:template match="v:typeNames">

[XSLT 2.0: you also can add xpath-default-namespace="uri" in the stylesheet section, to define a default namespace for all xpath-expressions. Therefore you dont have to prefix the namespace.]

III. Guessing on given input xml

<xsl:value-of select="source" /> -> <typeName recordType="source"..>SAMPLEST</typeName>

If you want to select the shown xml-node, you have to write one of the following:

absolute, without any context node:
 /v:typeNames/v:typeName[@recordType = 'source']

on context-node typeNames:
 v:typeName[@recordType = 'source']

[<xsl:value-of select="..."/> will return the text-node(s), e.g. "SAMPLEST"]


EDIT:

What if there are two tags.

First things first: <xsl:value-of in XSLT 1 can only work with 1 node! If the xpath expression matches more than one node, it will just process the first one!

Solve it like this way:

...
<results>
    <xsl:apply-templates select="v:typeName[@recordType = 'source']"/>
</results>
...

<xsl:template match="v:typeName[@recordType = 'source']">
    <source>
        <xsl:value-of select="."/>
    </source>
</xsl:template>

The apply-templates within results searches for all typeName..source. The matching template listens to that node and creates the xml <source>....