I have the following XML:
<?xml version="1.0" encoding="UTF-8"?>
<LaborTaskInterface>
<LaborTask thing1="a" thing2="c" thing3="d" thing4="e" thing5="f"
thing6="g" thing7="h" thing8="i" thing9="j">
<ltOverride unit_id="1" value="1" thing2="k" thing3="c" thing4="d" thing10="o"/>
<ltOverride unit_id="2" value="1" thing2="l" thing3="c" thing4="d" thing11="p"/>
<ltOverride unit_id="3" value="1" thing2="m" thing3="c" thing4="d" thing12="q"/>
<ltOverride unit_id="4" value="1" thing2="n" thing3="c" thing4="d" thing13="r"/>
</LaborTask>
<LaborTask thing1="aa" thing2="bb" thing3="dd" thing4="ee" thing5="ff"
thing6="gg" thing7="hh" thing8="ii" thing9="jj">
<ltOverride unit_id="11" value="11" thing2="kk" thing3="cc" thing4="dd" thing10="oo"/>
<ltOverride unit_id="22" value="12" thing2="ll" thing3="cc" thing4="dd" thing11="pp"/>
<ltOverride unit_id="33" value="13" thing2="mm" thing3="cc" thing4="dd" thing12="qq"/>
<ltOverride unit_id="44" value="14" thing2="nn" thing3="cc" thing4="dd" thing13="rr"/>
</LaborTask>
</LaborTaskInterface>
I am attempting to persist/copy each instance of LaborTask into each of the subsequent ItOverride and eliminate the LaborTask node so as to only have one table (ItOverride).
I am using the following XSLT-1.0 (as XSLT-1.0 is a requirement due to Microsoft Access):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
extension-element-prefixes="msxsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:key name="attr-by-name" match="ltOverride/@*" use="name()"/>
<xsl:key name="value" match="ltOverride/@*" use="concat(name(), generate-id(..))"/>
<xsl:template match="/LaborTaskInterface">
<xsl:variable name="xml" select="/" />
<!-- base -->
<xsl:variable name="base-attr" select="LaborTask/@*"/>
<xsl:variable name="base-elems">
<xsl:for-each select="$base-attr">
<xsl:element name="{name()}">
<xsl:value-of select="." />
</xsl:element>
</xsl:for-each>
</xsl:variable>
<!-- override -->
<xsl:variable name="override-columns">
<xsl:for-each select="LaborTask/ltOverride/@*[generate-id() = generate-id(key('attr-by-name', name())[1])]">
<col name="{name()}"/>
</xsl:for-each>
</xsl:variable>
<!-- output -->
<xsl:copy>
<xsl:for-each select="LaborTask/ltOverride">
<xsl:variable name="id" select="generate-id()" />
<xsl:copy>
<xsl:for-each select="$base-elems"/>
<xsl:copy-of select="$base-elems"/>
<xsl:for-each select="msxsl:node-set($override-columns)/col">
<xsl:variable name="name" select="@name" />
<xsl:variable name="dup">
<xsl:if test="$base-attr[name() = $name]">.2</xsl:if>
</xsl:variable>
<xsl:element name="{@name}{$dup}">
<!-- switch context back to input document in order to use key -->
<xsl:for-each select="$xml">
<xsl:value-of select="key('value', concat($name, $id))" />
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
This is the output I am getting which is not desired (I have attempted to loop the $base-elem):
<?xml version="1.0" encoding="utf-16"?>
<LaborTaskInterface>
<ltOverride>
<thing1>a</thing1>
<thing2>c</thing2>
<thing3>d</thing3>
<thing4>e</thing4>
<thing5>f</thing5>
<thing6>g</thing6>
<thing7>h</thing7>
<thing8>i</thing8>
<thing9>j</thing9>
<thing1>aa</thing1>
<thing2>bb</thing2>
<thing3>dd</thing3>
<thing4>ee</thing4>
<thing5>ff</thing5>
<thing6>gg</thing6>
<thing7>hh</thing7>
<thing8>ii</thing8>
<thing9>jj</thing9>
<unit_id>1</unit_id>
<value>1</value>
<thing2.2>k</thing2.2>
<thing3.2>c</thing3.2>
<thing4.2>d</thing4.2>
<thing10>o</thing10>
<thing11></thing11>
<thing12></thing12>
<thing13></thing13>
</ltOverride>
<ltOverride>
<thing1>a</thing1>
<thing2>c</thing2>
<thing3>d</thing3>
<thing4>e</thing4>
<thing5>f</thing5>
<thing6>g</thing6>
<thing7>h</thing7>
<thing8>i</thing8>
<thing9>j</thing9>
<thing1>aa</thing1>
<thing2>bb</thing2>
<thing3>dd</thing3>
<thing4>ee</thing4>
<thing5>ff</thing5>
<thing6>gg</thing6>
<thing7>hh</thing7>
<thing8>ii</thing8>
<thing9>jj</thing9>
<unit_id>2</unit_id>
<value>1</value>
<thing2.2>l</thing2.2>
<thing3.2>c</thing3.2>
<thing4.2>d</thing4.2>
<thing10></thing10>
<thing11>p</thing11>
<thing12></thing12>
<thing13></thing13>
</ltOverride>
<ltOverride>
<thing1>a</thing1>
<thing2>c</thing2>
<thing3>d</thing3>
<thing4>e</thing4>
<thing5>f</thing5>
<thing6>g</thing6>
<thing7>h</thing7>
<thing8>i</thing8>
<thing9>j</thing9>
<thing1>aa</thing1>
<thing2>bb</thing2>
<thing3>dd</thing3>
<thing4>ee</thing4>
<thing5>ff</thing5>
<thing6>gg</thing6>
<thing7>hh</thing7>
<thing8>ii</thing8>
<thing9>jj</thing9>
<unit_id>3</unit_id>
<value>1</value>
<thing2.2>m</thing2.2>
<thing3.2>c</thing3.2>
<thing4.2>d</thing4.2>
<thing10></thing10>
<thing11></thing11>
<thing12>q</thing12>
<thing13></thing13>
</ltOverride>
<ltOverride>
<thing1>a</thing1>
<thing2>c</thing2>
<thing3>d</thing3>
<thing4>e</thing4>
<thing5>f</thing5>
<thing6>g</thing6>
<thing7>h</thing7>
<thing8>i</thing8>
<thing9>j</thing9>
<thing1>aa</thing1>
<thing2>bb</thing2>
<thing3>dd</thing3>
<thing4>ee</thing4>
<thing5>ff</thing5>
<thing6>gg</thing6>
<thing7>hh</thing7>
<thing8>ii</thing8>
<thing9>jj</thing9>
<unit_id>4</unit_id>
<value>1</value>
<thing2.2>n</thing2.2>
<thing3.2>c</thing3.2>
<thing4.2>d</thing4.2>
<thing10></thing10>
<thing11></thing11>
<thing12></thing12>
<thing13>r</thing13>
</ltOverride>
<ltOverride>
<thing1>a</thing1>
<thing2>c</thing2>
<thing3>d</thing3>
<thing4>e</thing4>
<thing5>f</thing5>
<thing6>g</thing6>
<thing7>h</thing7>
<thing8>i</thing8>
<thing9>j</thing9>
<thing1>aa</thing1>
<thing2>bb</thing2>
<thing3>dd</thing3>
<thing4>ee</thing4>
<thing5>ff</thing5>
<thing6>gg</thing6>
<thing7>hh</thing7>
<thing8>ii</thing8>
<thing9>jj</thing9>
<unit_id>11</unit_id>
<value>11</value>
<thing2.2>kk</thing2.2>
<thing3.2>cc</thing3.2>
<thing4.2>dd</thing4.2>
<thing10>oo</thing10>
<thing11></thing11>
<thing12></thing12>
<thing13></thing13>
</ltOverride>
<ltOverride>
<thing1>a</thing1>
<thing2>c</thing2>
<thing3>d</thing3>
<thing4>e</thing4>
<thing5>f</thing5>
<thing6>g</thing6>
<thing7>h</thing7>
<thing8>i</thing8>
<thing9>j</thing9>
<thing1>aa</thing1>
<thing2>bb</thing2>
<thing3>dd</thing3>
<thing4>ee</thing4>
<thing5>ff</thing5>
<thing6>gg</thing6>
<thing7>hh</thing7>
<thing8>ii</thing8>
<thing9>jj</thing9>
<unit_id>22</unit_id>
<value>12</value>
<thing2.2>ll</thing2.2>
<thing3.2>cc</thing3.2>
<thing4.2>dd</thing4.2>
<thing10></thing10>
<thing11>pp</thing11>
<thing12></thing12>
<thing13></thing13>
</ltOverride>
<ltOverride>
<thing1>a</thing1>
<thing2>c</thing2>
<thing3>d</thing3>
<thing4>e</thing4>
<thing5>f</thing5>
<thing6>g</thing6>
<thing7>h</thing7>
<thing8>i</thing8>
<thing9>j</thing9>
<thing1>aa</thing1>
<thing2>bb</thing2>
<thing3>dd</thing3>
<thing4>ee</thing4>
<thing5>ff</thing5>
<thing6>gg</thing6>
<thing7>hh</thing7>
<thing8>ii</thing8>
<thing9>jj</thing9>
<unit_id>33</unit_id>
<value>13</value>
<thing2.2>mm</thing2.2>
<thing3.2>cc</thing3.2>
<thing4.2>dd</thing4.2>
<thing10></thing10>
<thing11></thing11>
<thing12>qq</thing12>
<thing13></thing13>
</ltOverride>
<ltOverride>
<thing1>a</thing1>
<thing2>c</thing2>
<thing3>d</thing3>
<thing4>e</thing4>
<thing5>f</thing5>
<thing6>g</thing6>
<thing7>h</thing7>
<thing8>i</thing8>
<thing9>j</thing9>
<thing1>aa</thing1>
<thing2>bb</thing2>
<thing3>dd</thing3>
<thing4>ee</thing4>
<thing5>ff</thing5>
<thing6>gg</thing6>
<thing7>hh</thing7>
<thing8>ii</thing8>
<thing9>jj</thing9>
<unit_id>44</unit_id>
<value>14</value>
<thing2.2>nn</thing2.2>
<thing3.2>cc</thing3.2>
<thing4.2>dd</thing4.2>
<thing10></thing10>
<thing11></thing11>
<thing12></thing12>
<thing13>rr</thing13>
</ltOverride>
</LaborTaskInterface>
You can see in the above output that the first instance of LaborTask (where thing1="a") is being brought into each of the 8 ItOverride.
This is the desired output (note how the first instance of LaborTask is carried into the first 4 ItOverride and the second instance of LaborTask is carried into the next 4 instances of ItOverride):
<LaborTaskInterface>
<ltOverride>
<thing1>a</thing1>
<thing2>c</thing2>
<thing2.2>k</thing2.2>
<thing3>d</thing3>
<thing3.2>c</thing3.2>
<thing4>e</thing4>
<thing4.2>d</thing4.2>
<thing5>f</thing5>
<thing6>g</thing6>
<thing7>h</thing7>
<thing8>i</thing8>
<thing9>j</thing9>
<unit_id>1</unit_id>
<value>1</value>
<thing10>o</thing10>
<thing11></thing11>
<thing12></thing12>
<thing13></thing13>
</ltOverride>
<ltOverride>
<thing1>a</thing1>
<thing2>c</thing2>
<thing2.2>l</thing2.2>
<thing3>d</thing3>
<thing3.2>c</thing3.2>
<thing4>e</thing4>
<thing4.2>d</thing4.2>
<thing5>f</thing5>
<thing6>g</thing6>
<thing7>h</thing7>
<thing8>i</thing8>
<thing9>j</thing9>
<unit_id>2</unit_id>
<value>1</value>
<thing10></thing10>
<thing11>p</thing11>
<thing12></thing12>
<thing13></thing13>
</ltOverride>
<ltOverride>
<thing1>a</thing1>
<thing2>c</thing2>
<thing2.2>m</thing2.2>
<thing3>d</thing3>
<thing3.2>c</thing3.2>
<thing4>e</thing4>
<thing4.2>d</thing4.2>
<thing5>f</thing5>
<thing6>g</thing6>
<thing7>h</thing7>
<thing8>i</thing8>
<thing9>j</thing9>
<unit_id>3</unit_id>
<value>1</value>
<thing10></thing10>
<thing11></thing11>
<thing12>q</thing12>
<thing13></thing13>
</ltOverride>
<ltOverride>
<thing1>a</thing1>
<thing2>c</thing2>
<thing2.2>n</thing2.2>
<thing3>d</thing3>
<thing3.2>c</thing3.2>
<thing4>e</thing4>
<thing4.2>d</thing4.2>
<thing5>f</thing5>
<thing6>g</thing6>
<thing7>h</thing7>
<thing8>i</thing8>
<thing9>j</thing9>
<unit_id>4</unit_id>
<value>1</value>
<thing10></thing10>
<thing11></thing11>
<thing12></thing12>
<thing13>r</thing13>
</ltOverride>
<ltOverride>
<thing1>aa</thing1>
<thing2>bb</thing2>
<thing2.2>kk</thing2.2>
<thing3>dd</thing3>
<thing3.2>cc</thing3.2>
<thing4>ee</thing4>
<thing4.2>dd</thing4.2>
<thing5>ff</thing5>
<thing6>gg</thing6>
<thing7>hh</thing7>
<thing8>ii</thing8>
<thing9>jj</thing9>
<unit_id>11</unit_id>
<value>11</value>
<thing10>oo</thing10>
<thing11></thing11>
<thing12></thing12>
<thing13></thing13>
</ltOverride>
<ltOverride>
<thing1>aa</thing1>
<thing2>bb</thing2>
<thing2.2>ll</thing2.2>
<thing3>dd</thing3>
<thing3.2>cc</thing3.2>
<thing4>ee</thing4>
<thing4.2>dd</thing4.2>
<thing5>ff</thing5>
<thing6>gg</thing6>
<thing7>hh</thing7>
<thing8>ii</thing8>
<thing9>jj</thing9>
<unit_id>22</unit_id>
<value>12</value>
<thing10></thing10>
<thing11>pp</thing11>
<thing12></thing12>
<thing13></thing13>
</ltOverride>
<ltOverride>
<thing1>aa</thing1>
<thing2>bb</thing2>
<thing2.2>mm</thing2.2>
<thing3>dd</thing3>
<thing3.2>cc</thing3.2>
<thing4>ee</thing4>
<thing4.2>dd</thing4.2>
<thing5>ff</thing5>
<thing6>gg</thing6>
<thing7>hh</thing7>
<thing8>ii</thing8>
<thing9>jj</thing9>
<unit_id>33</unit_id>
<value>13</value>
<thing10></thing10>
<thing11></thing11>
<thing12>qq</thing12>
<thing13></thing13>
</ltOverride>
<ltOverride>
<thing1>aa</thing1>
<thing2>bb</thing2>
<thing2.2>nn</thing2.2>
<thing3>dd</thing3>
<thing3.2>cc</thing3.2>
<thing4>ee</thing4>
<thing4.2>dd</thing4.2>
<thing5>ff</thing5>
<thing6>gg</thing6>
<thing7>hh</thing7>
<thing8>ii</thing8>
<thing9>jj</thing9>
<unit_id>44</unit_id>
<value>14</value>
<thing10></thing10>
<thing11></thing11>
<thing12></thing12>
<thing13>rr</thing13>
</ltOverride>
</LaborTaskInterface>
Thank you for all help.
CodePudding user response:
The only thing this doesn't do is sort the final elements in the order you specified. You can figure that if needed. Put this in the debugger and trace through it, if needed to understand what the code is doing.
<xsl:template match="LaborTaskInterface">
<xsl:copy>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="LaborTask">
<xsl:variable name="childAttributeNames">
<xsl:for-each select=".//*/@*">
<xsl:element name="name">
<xsl:value-of select="name()"/>
</xsl:element>
</xsl:for-each>
</xsl:variable>
<!-- Use your own namespace instead of msxml. -->
<xsl:variable name="childAttributeNameList" select="msxml:node-set($childAttributeNames)"/>
<xsl:variable name="distintChildAttributeNames">
<xsl:copy-of select="$childAttributeNameList/name[not(. = preceding-sibling::name)]"/>
</xsl:variable>
<!-- Use your own namespace instead of msxml. -->
<xsl:variable name="distintChildAttributeNameList" select="msxml:node-set($distintChildAttributeNames)"/>
<xsl:apply-templates select="node()">
<xsl:with-param name="LaborTaskAttributes" select="@*"/>
<xsl:with-param name="distintChildAttributeNameList" select="$distintChildAttributeNameList"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="ltOverride">
<xsl:param name="LaborTaskAttributes"/>
<xsl:param name="distintChildAttributeNameList"/>
<xsl:variable name="ltOverride" select="@*"/>
<xsl:variable name="emptyAttributes">
<xsl:element name="holder">
<xsl:for-each select="$distintChildAttributeNameList/name">
<xsl:variable name="name" select="."/>
<xsl:if test="not($LaborTaskAttributes[name() = $name] or $ltOverride[name() = $name])">
<xsl:attribute name="{$name}"/>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:variable>
<!-- Use your own namespace instead of msxml. -->
<xsl:variable name="emptyAttributesList" select="msxml:node-set($emptyAttributes)"/>
<xsl:copy>
<xsl:apply-templates select="$LaborTaskAttributes|@*|$emptyAttributesList/holder/@*">
<xsl:sort select="name()" data-type="text" order="ascending"/>
<xsl:with-param name="LaborTaskAttributes" select="$LaborTaskAttributes"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="@*">
<xsl:param name="LaborTaskAttributes"/>
<xsl:variable name="id" select="generate-id(.)"/>
<xsl:variable name="nm" select="name()"/>
<xsl:variable name="name">
<xsl:choose>
<xsl:when test="not($LaborTaskAttributes[name() = $nm])">
<xsl:value-of select="name()"/>
</xsl:when>
<xsl:when test="$LaborTaskAttributes[generate-id(.) = $id]">
<xsl:value-of select="name()"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat(name(), '.2')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:element name="{$name}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:template>
<xsl:template match="node()">
<xsl:param name="LaborTaskAttributes"/>
<xsl:param name="distintChildAttributeNameList"/>
<xsl:apply-templates select="node()">
<xsl:with-param name="LaborTaskAttributes" select="$LaborTaskAttributes"/>
<xsl:with-param name="distintChildAttributeNameList" select="$distintChildAttributeNameList"/>
</xsl:apply-templates>
</xsl:template>