Change 2 attributes of an XML with XSLT

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 where it reads name="INFO" get 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 (very large) file 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 join the two transformations in one XSLT file, it gives me an error (I do not really know how to do this)?

Can anyone help? Thanks

    
asked by anonymous 11.04.2017 / 18:06

1 answer

0

If you add the second template in the first XSLT, it does not give an error. What you should not do is simply add these two templates in the first XSLT, as there is ambiguity. The first one copies all elements * and attributes * and in the second XSLT there is one that copies all node () (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>
    
04.12.2017 / 22:01