i have an large xml-file, where a part of the file has the following structure:
How can i replace all "abc..." in the xml-elements with "xyz...", using XSLT?
The basic condition are:
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.
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>
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.