Change 2 attributes of an XML with XSLT

Asked

Viewed 174 times

0

I have the following XML:

<?xml version="1.0" encoding="WINDOWS-1252"?>
-<NewDataSet>
-<xs:schema xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="" id="NewDataSet">
  -<xs:element msdata:Locale="" msdata:MainDataTable="INFO" msdata:IsDataSet="true" name="NewDataSet">
    -<xs:complexType>
      -<xs:choice maxOccurs="unbounded" minOccurs="0">
        -<xs:element msdata:Locale="" name="INFO">

(...)

a) I need to change the last line with XSLT to which name="INFO" is spelled name="INFO2" and the following xslt works:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
version="1.0">
<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>
<xsl:template match="*|@*">
    <xsl:copy>
        <xsl:apply-templates select="*|@*"/>
    </xsl:copy>
</xsl:template>
<xsl:template match="xs:element[@name='NewDataSet']/xs:complexType/xs:choice/xs:element">
    <xsl:copy>
        <xsl:attribute name="name">INFO2</xsl:attribute>
        <xsl:apply-templates select="@*[name() != 'name']|*"/>
    </xsl:copy>
</xsl:template>
</xsl:stylesheet>

b) Now I need to make a second change to the rest of the xml file (very large) and the following xslt also works:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
</xsl:template>
<xsl:template match="INFO">
    <INFO2><xsl:apply-templates select="@*|node()" /></INFO2>
</xsl:template>

But when I try to merge the 2 transformations into one XSLT file gives me error (actually I don’t even know how to do that)?

Can anyone help? Thank you

1 answer

0

If you add the second template in the first XSLT there is no error. What you should not do is simply add these two templates in the first XSLT, because there is ambiguity. The first of them copies all the * and @* elements and attributes and in the second XSLT there is one that copies all Node() nodes (includes elements) and @*attributes. Some processors (not all - some just print Warning) may fail because of this, and if there are elements with text content it will be lost.

The XSLT below is correct and should work:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
    version="1.0">

    <xsl:strip-space elements="*"/>
    <xsl:output indent="yes"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="xs:element[@name='NewDataSet']/xs:complexType/xs:choice/xs:element">
        <xsl:copy>
            <xsl:attribute name="name">INFO2</xsl:attribute>
            <xsl:apply-templates select="@*[name() != 'name']|*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="INFO">
        <INFO2><xsl:apply-templates select="@*|node()" /></INFO2>
    </xsl:template>

</xsl:stylesheet>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.