I have xml which is structed like following
<root>
<PNode>
<node1>
<node1Child>data</node1Child>
<node2Child>data</node2Child>
</node1>
</PNode>
<SecondNode>
<node1>
<node1Child>
<child>data</child>
</node1Child>
</node1>
</SecondNode>
</root>
I want output using genric xslt because i have many xml to convert to this format.
<root>
<Pnode-node1-node1Child>data</Pnode-node1-node1Child>
<Pnode-node1-node2Child>data</Pnode-node1-node2Child>
<SecondNode-node1-node1child-child>data</SecondNode-node1-node1child-child>
</root>
It could be more deep or less.
can I do it by XSLT pls give any example or reference
I want to do it to generate PDF from sql server 2k8 r2 rdl. because rdl do not accept nested xml so need to flatten it.
The standard way to transform XML data into other formats is by Extensible Stylesheet Language Transformations (XSLT). You can use the built-in XSLTRANSFORM function to convert XML documents into HTML, plain text, or different XML schemas. XSLT uses stylesheets to convert XML into other data formats.
Execute an XSLT transformation from an XML fileOpen an XML document in the XML editor. Associate an XSLT style sheet with the XML document. Add an xml-stylesheet processing instruction to the XML document.
The XSLT 2.0 engine is backwards compatible. The only time the backwards compatibility of the XSLT 2.0 engine comes into effect is when using the XSLT 2.0 engine to process an XSLT 1.0 stylesheet.
XSLT is a language for transforming XML documents into another XML documents. XSL includes an XML vocabulary for specifying formatting. XSL specifies the styling of an XML document by using XSLT to describe how the document is transformed into another XML document that uses the formatting vocabulary.
This transformation:
<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="/*">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
<xsl:template match="text()">
<xsl:variable name="vCompName">
<xsl:for-each select="ancestor::*[not(position() =last())]">
<xsl:value-of select="translate(name(), ':', '_')"/>
<xsl:if test="not(position()=last())">-</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:element name="{$vCompName}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<root>
<PNode>
<node1>
<node1Child>data</node1Child>
<node2Child>data</node2Child>
</node1>
</PNode>
<SecondNode>
<node1>
<node1Child>
<child>data</child>
</node1Child>
</node1>
</SecondNode>
</root>
produces the wanted, correct result:
<root>
<PNode-node1-node1Child>data</PNode-node1-node1Child>
<PNode-node1-node2Child>data</PNode-node1-node2Child>
<SecondNode-node1-node1Child-child>data</SecondNode-node1-node1Child-child>
</root>
Explanation:
Besides wrapping the document in a root
top element, there is just a single template. It matches any non-whitespace-only text node.
The nodeset of all element-ancestors except the first one in document order (which is the last in the reverse axis ancestor::
) are string-joined with a '-'
character and an element is constructed with this string as a name.
Before the string-join operation in 2. above, every name is modified so that any ':'
character in it is substituted by an underline character. This makes the transformation not produce invalid compound names if there are namespace prefixes in some names.
Finally, the current text node is copied as a child of the dynamically-constructed element.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With