tags:

views:

47

answers:

2

Hi,

Please find the 2 XML's

Input XML-

<feed xmlns:es="http://ucmservice"&gt;
 <element>
<es:RepositoryDetails>
    <es:Repository Type="DatabaseRepository" />
        <es:ConnetionDetails>
        <es:Param MigrationSetId="439" />
    </es:ConnetionDetails>
</es:RepositoryDetails>
<es:DocProperties>
    <es:UniqueDocId Value="_1_15">
            <es:DocProperty propertyName="EmployeeName">
                <es:PropValues>
                  <es:PropValue>Index</es:PropValue>
                </es:PropValues>
            </es:DocProperty>
            <es:DocProperty propertyName="EmployeeAddress">" +
                      <es:PropValues>
                        <es:PropValue>Gurgaon</es:PropValue>
                      </es:PropValues>
                </es:DocProperty>
                <es:DocProperty propertyName="Salary">
                      <es:PropValues>
                        <es:PropValue>15000</es:PropValue>
                      </es:PropValues>
                </es:DocProperty>
        </es:UniqueDocId>
    </es:DocProperties>
</element>

<element>
<es:RepositoryDetails>
    <es:Repository Type="DatabaseRepository" />
        <es:ConnetionDetails>
        <es:Param MigrationSetId="439" />
    </es:ConnetionDetails>
</es:RepositoryDetails>
<es:DocProperties>
    <es:UniqueDocId Value="_1_15">
            <es:DocProperty propertyName="EmployeeName">
                <es:PropValues>
                  <es:PropValue>Index1</es:PropValue>
                </es:PropValues>
            </es:DocProperty>
            <es:DocProperty propertyName="EmployeeAddress">" +
                      <es:PropValues>
                        <es:PropValue>Delhi</es:PropValue>
                      </es:PropValues>
                </es:DocProperty>
                <es:DocProperty propertyName="Salary">
                      <es:PropValues>
                        <es:PropValue>25000</es:PropValue>
                      </es:PropValues>
                </es:DocProperty>
        </es:UniqueDocId>
    </es:DocProperties>
</element>

<element>
<es:RepositoryDetails>
    <es:Repository Type="Trim" />
        <es:ConnetionDetails>
        <es:Param MigrationSetId="439" />
    </es:ConnetionDetails>
</es:RepositoryDetails>
<es:DocProperties>
    <es:UniqueDocId Value="_1_15">
            <es:DocProperty propertyName="EmployeeName">
                <es:PropValues>
                  <es:PropValue>Quality</es:PropValue>
                </es:PropValues>
            </es:DocProperty>
            <es:DocProperty propertyName="EmployeeAddress">" +
                      <es:PropValues>
                        <es:PropValue>Mumbai</es:PropValue>
                      </es:PropValues>
                </es:DocProperty>
                <es:DocProperty propertyName="Salary">
                      <es:PropValues>
                        <es:PropValue>20000</es:PropValue>
                      </es:PropValues>
                </es:DocProperty>
        </es:UniqueDocId>
    </es:DocProperties>
</element>

<element>
<es:RepositoryDetails>
    <es:Repository Type="DatabaseRepository" />
        <es:ConnetionDetails>
        <es:Param MigrationSetId="439" />
    </es:ConnetionDetails>
</es:RepositoryDetails>
<es:DocProperties>
    <es:UniqueDocId Value="_1_15">
            <es:DocProperty propertyName="EmployeeName">
                <es:PropValues>
                  <es:PropValue>Index</es:PropValue>
                </es:PropValues>
            </es:DocProperty>
            <es:DocProperty propertyName="EmployeeAddress">" +
                      <es:PropValues>
                        <es:PropValue>Gurgaon</es:PropValue>
                      </es:PropValues>
                </es:DocProperty>
                <es:DocProperty propertyName="Salary">
                      <es:PropValues>
                        <es:PropValue>21000</es:PropValue>
                      </es:PropValues>
                </es:DocProperty>
        </es:UniqueDocId>
    </es:DocProperties>
</element>


<element>
<es:RepositoryDetails>
    <es:Repository Type="Trim" />
        <es:ConnetionDetails>
        <es:Param MigrationSetId="439" />
    </es:ConnetionDetails>
</es:RepositoryDetails>
<es:DocProperties>
    <es:UniqueDocId Value="_1_15">
            <es:DocProperty propertyName="EmployeeName">
                <es:PropValues>
                  <es:PropValue>Index1</es:PropValue>
                </es:PropValues>
            </es:DocProperty>
            <es:DocProperty propertyName="EmployeeAddress">" +
                      <es:PropValues>
                        <es:PropValue>Gurgaon</es:PropValue>
                      </es:PropValues>
                </es:DocProperty>
                <es:DocProperty propertyName="Salary">
                      <es:PropValues>
                        <es:PropValue>15000</es:PropValue>
                      </es:PropValues>
                </es:DocProperty>
        </es:UniqueDocId>
    </es:DocProperties>
</element></feed>

Required Output XML-

<tree>
<item level="0" name="DatabaseRepository">
    <item level="1" name="Index">
        <item level="2" name="Gurgaon"/>
        <item level="2" name="Mumbai"/>
    </item>
    <item level="1" name="Index1">
        <item level="2" name="Delhi"/>
    </item>
</item>
<item level="0" name="Trim">
    <item level="1" name="Quality">
        <item level="0" name="Mumbai"/>
    <item level="1" name="Index1">
        <item level="0" name="Gurgaon"/>
    </item>
</item>
</tree>

I don't know how to implement it. I tried few things in XSL and Javascript but they are not enough.

A: 

I don't understand why you would want to do this - as far as I understand this could result in invalid xml.

That said, have you tried changing the xslt output type to text?

<xsl:output method="text" />

See http://www.w3schools.com/xsl/el_output.asp for details on where this element should be placed in your xslt document (just inside the <xsl:stylesheet> element)

Kragen
I've added <xsl:output method="xml" /> in my stylesheet. the part here is only one template of the whole stylesheet. i feel the {match="element"} is creating some confusion. The "element" is the name of the node present in the XML thats why I am using it.
+2  A: 

XSLT is about tree, not tags. If your output method is not text you can't produce a non-wellformed tree. And that's a feature!

I'm sure that your desired output can be produce with proper XSLT. You need to post an input sample and desired output.

EDIT: Also, in order to help you, you must to revert this sentence:

"i want to close a node only if a poarticular condition is true"

For: I want to add some template if a particular condition is true

EDIT 2: Now with input and output, it's look like you want to group by two keys. So, this stylesheet:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:es="http://ucmservice" exclude-result-prefixes="es">
    <xsl:key name="ByType" match="element" use="es:RepositoryDetails/es:Repository/@Type"/>
    <xsl:key name="ByType-Name" match="es:UniqueDocId" use="concat(../../es:RepositoryDetails/es:Repository/@Type,'++',es:DocProperty[@propertyName='EmployeeName']/es:PropValues/es:PropValue)"/>
    <xsl:template match="text()"/>
    <xsl:template match="feed">
        <tree>
            <xsl:apply-templates/>
        </tree>
    </xsl:template>
    <xsl:template match="element"/>
    <xsl:template match="element[count(.|key('ByType',es:RepositoryDetails/es:Repository/@Type)[1])=1]">
        <item level="0" name="{es:RepositoryDetails/es:Repository/@Type}">
            <xsl:apply-templates select="key('ByType',es:RepositoryDetails/es:Repository/@Type)/*"/>
        </item>
    </xsl:template>
    <xsl:template match="es:UniqueDocId"/>
    <xsl:template match="es:UniqueDocId[count(.|key('ByType-Name',concat(../../es:RepositoryDetails/es:Repository/@Type,'++',es:DocProperty[@propertyName='EmployeeName']/es:PropValues/es:PropValue))[1])=1]">
        <item level="1" name="{es:DocProperty[@propertyName='EmployeeName']/es:PropValues/es:PropValue}">
            <xsl:apply-templates select="key('ByType-Name',concat(../../es:RepositoryDetails/es:Repository/@Type,'++',es:DocProperty[@propertyName='EmployeeName']/es:PropValues/es:PropValue))/*"/>
        </item>
    </xsl:template>
    <xsl:template match="es:DocProperty[@propertyName='EmployeeAddress']/es:PropValues/es:PropValue">
        <item level="2" name="{.}" />
    </xsl:template>
</xsl:stylesheet>

Output:

<tree>
    <item level="0" name="DatabaseRepository">
        <item level="1" name="Index">
            <item level="2" name="Gurgaon" />
            <item level="2" name="Gurgaon" />
        </item>
        <item level="1" name="Index1">
            <item level="2" name="Delhi" />
        </item>
    </item>
    <item level="0" name="Trim">
        <item level="1" name="Quality">
            <item level="2" name="Mumbai" />
        </item>
        <item level="1" name="Index1">
            <item level="2" name="Gurgaon" />
        </item>
    </item>
</tree>

Note: Your desired output has some mistakes (there is no DatabaseRepository-Index-Mumbai) so I can't tell if you really want item[@name='Trim'] grandchilds with @leve 2 or 0 as it was written.

Alejandro
I've edited the question and now the input sample and desired output are there. I might have used some wrong termlogy, my apology for that.
Amazing... Thats exactly what i needed.Just one more thing.. from where have you learn this level of XSL.. :)I've tried so many tutorials and books, all the time I end up with some general basic concepts. A lot many terms in this XSL are the first time I've come across. I can't even think of creating such XSL.Thanks a lot Alejandro.
@himit: I'm glad that this is helpful. If you accept this answer it could help others, too. About learning XSLT, I'm not an authority but an enthusiastic. First of all, you need to understand declarative paradigm: binding input with output through declarations, so there is no imperative process but a relationship description. Covering that, you need to study the XSLT and XPath specifications and practice good XSLT examples like in here, FAQs from www.dpawson.co.uk and expert site (as example, look up for blogs and site from best XSLT responders in here)
Alejandro
1 more thing Alejandro, if in case, i don't want the first grouping on the basis of repository and i want a simple grouping on the basis of properties, then which part do i need to change. i.e. if level=0 name="DatabseRepository" needs to be change to any 'propertyName' say 'EmployeeSalary'... I tried few permutations but couldn't get the right output.
@himit: Best practice is to ask a new question. This time, provide input sample and desired output.
Alejandro
Thanks Alejandro. I tried on my own keeping this XSL as a base XSL and were able to achieve the desired output. Its really a great and a very helpful XSL for me. there are still few things which I am not clear about, like, I am still unclear with the concept of concating the nodes in the second key function i.e.<xsl:key name="ByType-Name" match="es:UniqueDocId" use="concat(../../es:RepositoryDetails/es:Repository/@Type,'++',es:DocProperty[@propertyName='EmployeeName']/es:PropValues/es:PropValue)"/> :)
@himit: As far as I undertands your last question, I think you need to group by one key only: `<xsl:key name="kPropertyByName" match="es:DocProperty" use="@propertyName"/>` and then the rule `<xsl:template match="es:DocProperty[count(.|key('kPropertyByName',@propertyName)[1])=1]">`
Alejandro