Home > database >  How to split a comma-separated value attribute into two different values attributes in XSLT 1.0
How to split a comma-separated value attribute into two different values attributes in XSLT 1.0

Time:07-14

I have this XML

<?xml version="1.0" encoding="UTF-8"?>
<WORK>
    <TASKS>
        <OFFICE PosAB="(1,2)" Home office="yes" name="Accountant">
            <SECTION>
                <business Key="Code OFFICE" type="Position"> BOSS </business>
            </SECTION>
            <schedule>
                <sortie hours="10"/>
            </schedule>
        </OFFICE>
        <OFFICE PosAB="(10,11)" Home office="no" name="Engineer">
            <SECTION>
                <business Key="Code OFFICE" type="Position"> TECH </business>
            </SECTION>
            <schedule>
                <sortie hours="5"/>
            </schedule>
        </OFFICE>
    </TASKS>
</WORK>

I want to separate the PosAB attribute in two separating, also the value of the attribute, and have this as result:

<?xml version="1.0" encoding="UTF-8"?>
<WORK>
    <TASKS>
        <OFFICE PosA="1" PosB="2" Home office="yes" name="Accountant">
            <SECTION>
                <business Key="Code OFFICE" type="Position"> BOSS </business>
            </SECTION>
            <schedule>
                <sortie hours="10"/>
            </schedule>
        </OFFICE>
        <OFFICE PosA="10" PosB="11" Home office="NO" name="Engineer">
            <SECTION>
                <business Key="Code OFFICE" type="Position"> TECH </business>
            </SECTION>
            <schedule>
                <sortie hours="5"/>
            </schedule>
        </OFFICE>
    </TASKS>
</WORK>

This is the XSLT that I have

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:str="http://exslt.org/strings" 
extension-element-prefixes="str">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

    <xsl:template match="node()|@*">
     <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
    </xsl:template>
    <xsl:template match="OFFICE/@PosAB">
        <xsl:for-each select="str:tokenize(@CoordXY, ',')">
            <xsl:attribute name="PosA">
                <xsl:value-of select="substring-after(., ',')" />
            </xsl:attribute>
            <xsl:attribute name="PosB">
                <xsl:value-of select="substring-before(., ',')" />
            </xsl:attribute>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

At the moment of executing the code the xslt does not generate what I need, how can I write the xslt to achieve what is described above?

CodePudding user response:

Try:

XSLT 1.0

<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>

<xsl:template match="@PosAB">
    <xsl:variable name="ab" select="translate(., '()', '')" />
    <xsl:attribute name="PosA">
        <xsl:value-of select="substring-before($ab, ',')" />
    </xsl:attribute>
    <xsl:attribute name="PosB">
        <xsl:value-of select="substring-after($ab, ',')" />
    </xsl:attribute>
</xsl:template>

</xsl:stylesheet>

Note that this assumes the original attribute contains no parentheses other than the surrounding ones.

  • Related