Question

i have an large xml-file, where a part of the file has the following structure:

xml structure

How can i replace all "abc..." in the xml-elements with "xyz...", using XSLT?

The basic condition are:

  • xml - Version 1.0
  • no EXSLT, no Java
  • do the replacment only for the child-nodes of the node : "base.data.row"
  • i will use the XalanTransformer in C++ to do the transformation

All i got now, is only the identity-transformation in XSLT and now i searched for a way to replace the names of the childs of the node "base.data.row". But i do not know how.

Here the xml:

<?xml version="1.0" encoding="utf-8"?>
<base>
  <data>
    <row type="">
      <abc_dimension />
      <abc_weight />
      <numOf />
      <abcValues>
        <val1 />
        <val2 />
      </abcValues>
      <graph />
    </row>
    <row type="">
      <abc_dimension />
      <abc_weight />
      <numOf />
      <abcValues>
        <val1 />
        <val2 />
      </abcValues>
      <graph />
    </row>
    <row type="">
      <abc_dimension />
      <abc_weight />
      <numOf />
      <abcValues>
        <val1 />
        <val2 />
      </abcValues>
      <graph />
    </row>
  </data>
</base>

I tried the xslt of "michael.hor257k" here (http://xslttest.appspot.com/) and it worked! BUT when i use it with the XalanTransformer in C++, it returns only the values of the xml nodes. I use the XalanTransformer the following way:

XALAN_USING_XERCES( XMLPlatformUtils );
XALAN_USING_XALAN( XalanTransformer );

XMLPlatformUtils::Initialize();
XalanTransformer::initialize();

const char* xmlIn = "origXML.xml";
const char* xslIn = "transformation_template.xslt"; //the xslt of michael.hor257k
const char* xmlOut = "origXMLTransformed-out.xml"; //returns only the values of the xml nodes

XalanTransformer theXalanTransformer;
int a_errNumber = theXalanTransformer.transform( xmlIn, xslIn, xmlOut );               

XalanTransformer::terminate();
XMLPlatformUtils::Terminate();
XalanTransformer::ICUCleanUp();

Fixed it, seems like there was somewhere a typo. Seems that XalanTransformer used the default template rules, which will result in outputting all the text nodes in the whole source document.

Was it helpful?

Solution

Try:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" 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>

<!-- rename -->
<xsl:template match="base/data/row/*[starts-with(name(), 'abc')]">
    <xsl:element name="xyz{substring-after(name(), 'abc')}">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

OTHER TIPS

try using following way, which might help you. I tried by writing some sample xml and xsl to work with element names and it works fine.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">
    <xsl:template match="/">
        <xsl:element name="base">
                    <xsl:for-each select="base/data">
                <xsl:element name="row">
                    <xsl:for-each select="row/*">
                        <xsl:choose>
                            <xsl:when test="starts-with(name(.),'abc')">
                                <xsl:element name="{concat('pqr', substring-after(name(.), 'abc'))}">
                                    <xsl:value-of select="." />
                                </xsl:element>
                            </xsl:when>
                            <xsl:otherwise>
                                <xsl:element name="{name(.)}">
                                    <xsl:value-of select="." />
                                </xsl:element>
                            </xsl:otherwise>
                        </xsl:choose>
                    </xsl:for-each>
                </xsl:element>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

sample xml using which I tried.

<base>
  <data>
    <row>
      <type>110</type>
      <abc_dimension>dimension value 1</abc_dimension>
      <abc_weight>weight value 1</abc_weight>
      <nomof>x1</nomof>
    </row>
    <row>
      <type>111</type>
      <abc_dimension>dimension value 2</abc_dimension>
      <abc_weight>weight value 2</abc_weight>
      <nomof>x2</nomof>
    </row>
  </data>
</base>

Thanks,
Gaurav

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top