Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Output entire XML as an attribute

I'm fairly new to XML and XSL Stylesheets, and I've been tasked with creating a stylesheet for one of our clients. I have already created a stylesheet that outputs an XML in the following format:

<Trip TripType="Normal">
    <Plan BeginTime="2011-08-13T10:00:00" UserDefinedTripID="777" UserDefinedRouteID="777">
        <PlanStop ArrivalTime="2011-08-13T15:30:00" ArrivalLock="true" SiteID="1" PassThru1="test1" PassThru2="test2" PassThru3="test3" PassThru4="test4">
            <PlanNote Line1="Freeform Text" Line2="Line2" Line3="Line3" />
            <PlanCargo Duration="60" BillID="" Weight="100" Units="100.0" XUnitTypeID="10" Action="Pick" />
            <PlanNote Line1="Freeform Text" Line2="Line2" Line3="Line3" />
            <PlanCargo Duration="60" BillID="" Weight="100" Units="100.0" XUnitTypeID="12" Action="Pick" />
        </PlanStop>
    </Plan>
</Trip>

I need to take the output and insert the contents into an attribute within the Trip element to look like this:

<Trip TripID="-1" CurrentRevisionNumber="1" IsDispatch="1" IsActive="0" 
IsComplete="0" OrganizationID="4"
TripData="&lt;Trip TripType=&quot;Normal&quot;&gt;
  &lt;Plan BeginTime=&quot;2011-08-13T10:00:00&quot; UserDefinedTripID=&quot;777&quot;
  UserDefinedRouteID=&quot;777&quot;&gt;
    &lt;PlanStop ArrivalTime=&quot;2011-08-13T10:00:00&quot; ArrivalLock=&    quot;true&quot; SiteID=&quot;1&quot; PassThru1=&quot;test1&quot; PassThru2=&    quot;test2&quot; PassThru3=&quot;test3&quot; PassThru4=&quot;test4&quot;&gt;
    &lt;PlanCargo Duration=&quot;45&quot; BillID=&quot;&quot; Weight=&    quot;100&quot; Units=&quot;100.0&quot; XUnitTypeID=&quot;9&quot; Action=&quot;Pick&quot;     /&gt;
    &lt;/PlanStop&gt; />

So in other words, I need to take an existing XML output and put it in an attribute while performing some character transformations.

Yes, it is extremely ugly, but this is how they want it. I was thinking of making another XSL that will copy over the XML output from the original XSL transformation and place it in an attribute while converting <, >, ", etc into < , > , " , etc (not sure what they're called).

I've scoured the internet for solutions, but I can't seem to find any that are quite like this (I'd imagine that's because this is a ridiculous request). I can provide my original XSL if necessary, but I'd rather not change it, if possible.

Thanks in advance!

like image 365
user1546753 Avatar asked Dec 20 '22 18:12

user1546753


1 Answers

I would save myself time, effort and depression from others' stupidity and will implement this with a tiny transformation that uses a tiny extension function.

Here is example using the .NET XslCompiledTransform XSLT processor:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
 xmlns:my="my:my" exclude-result-prefixes="msxsl my">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/*">
  <t stupid="{my:stringize(.)}"/>
 </xsl:template>

 <msxsl:script language="c#" implements-prefix="my">
  public string stringize(XPathNavigator doc)
  {
   return doc.InnerXml;
  }
 </msxsl:script>
</xsl:stylesheet>

When applied on any XML document, it produces the top element with a stupid attribute that contains the escaped representation of the body of the top element.

For example, when the transformation is applied on this XML document:

<t>
  <a>
    <b x="y">
      <!--  Comment here -->
      <?aPI ?>
    </b>
  </a>
</t>

the wanted result is produced:

<t stupid="&#xD;&#xA;  &lt;a&gt;&#xD;&#xA;    &lt;b x=&quot;y&quot;&gt;&#xD;&#xA;      &lt;!--  Comment here --&gt;&#xD;&#xA;      &lt;?aPI?&gt;&#xD;&#xA;    &lt;/b&gt;&#xD;&#xA;  &lt;/a&gt;&#xD;&#xA;" />

A transformation implementing the same idea most probably can be written for almost every XSLT processor with an extension function that itself can be written in variety of programming languages.

like image 178
Dimitre Novatchev Avatar answered Jan 01 '23 09:01

Dimitre Novatchev