0

I have a XML and XSL like this:

XML

<definitions>
  <process id="Process_1">
    <Task id="Task_1yh7nak" name="Add">
      <Steps>
        <Step id="Step_1" Order="1">
          <Form>
            <form-template>
              <fields>
                <field type="text" label="start" id="text-14708410685"></field>
                <field type="text" label="end"  id="text-5651568987"></field>
                <field type="button" subtype="button" label="Button" id="button-1470841070721"></field>
              </fields>
            </form-template>
          </Form>
        </Step>        
      </Steps>
    </Task>
  </process>
</definitions>

XSL

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"                              
                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                              xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xsl:output method = "text" omit-xml-declaration = "no" indent = "no" encoding="Windows-1252"/> 

 <!-- Start the code generation here. -->
  <xsl:template match ="*">

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml.Linq;
    using System.Windows.Forms;

namespace Core
{
  public static class DynamicCode
  {
  <xsl:for-each select="/definitions/process/Task">
    public static string <xsl:value-of select="@id"/>_GetStartForm()
    {
     string formContent = "<xsl:for-each select="Steps/Step[@Order='1']/Form/form-template/fields/field">
      <!--Switch Case for type of controls -->
      <xsl:choose>          
        <xsl:when test="@type='text'">
          <h2> textbox </h2>
          <input>
            <xsl:attribute name="value">
              <xsl:value-of select="@label"/>
            </xsl:attribute>
            <xsl:attribute name="id">
              <xsl:value-of select="@id"/>
            </xsl:attribute>
          </input>
          <br/>
        </xsl:when>

        <xsl:when test="@type='button'">
          <h2> button </h2>
          <input type="button">
            <xsl:attribute name="value">
              <xsl:value-of select="@label"/>
            </xsl:attribute>
            <xsl:attribute name="id">
              <xsl:value-of select="@id"/>
            </xsl:attribute>
          </input>
          <br/>
        </xsl:when>
      </xsl:choose>

  </xsl:for-each>";
     return formContent;
    }   
   </xsl:for-each>
  }
}

</xsl:template>
</xsl:stylesheet>

I transform XML with this XSL (XSLT 1.0).

Output

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Windows.Forms;

namespace Core
{
  public static class DynamicCode
  {

    public static string Task_1yh7nak_GetStartForm()
    {
     string formContent = " textbox  textbox  button ";
     return formContent;
    }   

  }
}

Online output:http://xsltransform.net/pPJ8LUY/1

I try to get full html content in fields tag as string format. I need to this content for fill Literal in web page.

<h2> textbox </h2>
<input id="text-14708410685" value="start"></input>
<h2> textbox </h2>
<input id="text-5651568987" value="end"></input>
<h2> button </h2>
<input type="button" id="button-1470841070721" value="submit"></input>

But in output, I have only value of h2 tag.

string formContent = " textbox  textbox  button ";

It would be very helpful if someone could explain solution for this problem.

6
  • 1
    If you want your elements like the input elements to show up then you need to use the xsl:output method="html" or xml, the text output method you use is supposed to output the plain text in text nodes, but not any markup of element nodes. Commented Aug 31, 2016 at 10:04
  • @MartinHonnen thx,I didn't notice to it. Commented Aug 31, 2016 at 10:38
  • @MartinHonnen One question, The output should be a C# class but attributes have ". In string, it makes error. I can't use \ before and after them in xsl:value-of. Commented Aug 31, 2016 at 11:45
  • I understand the problem but I don't think there is an easy way around it in XSLT 1.0 or 2.0. In XSLT 3.0 I would probably use literal result elements to construct the HTML elements in a variable, the use the serialize function to serialize and then finally use replace to make sure any quotes " are escaped as \" for the C# string literal. Commented Aug 31, 2016 at 12:03
  • 1
    It is not the value-of that creates the nested, unescaped quotes, you are outputting literal text with double quotes and the serialization of result elements with attributes, and these are serialized with double quotes. As said, there is no easy and nice way out, unless you can use XSLT 3.0. Or you go the way proposed by Tim in his answer where you use output method text and then write code to construct the HTML markup with all necessary escaping of quotes done by hand to allow you to include the HTML markup inside of a C# string literal. Commented Aug 31, 2016 at 13:09

1 Answer 1

1

It's not that pleasant to look at, but in XSLT 1.0 you will have to manually escape all the HTML tags you wish to output.

Try this XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"                              
                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                              xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xsl:output method = "text" omit-xml-declaration = "no" indent = "no" encoding="Windows-1252"/> 

 <!-- Start the code generation here. -->
  <xsl:template match ="*">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Windows.Forms;

namespace Core
{
  public static class DynamicCode
  {
  <xsl:for-each select="/definitions/process/Task">
    public static string <xsl:value-of select="@id"/>_GetStartForm()
    {
     string formContent = "<xsl:for-each select="Steps/Step[@Order='1']/Form/form-template/fields/field">
      <!--Switch Case for type of controls -->
      <xsl:choose>          
        <xsl:when test="@type='text'">
          <xsl:text>&lt;h2&gt;textbox&lt;/h2&gt;</xsl:text>
          <xsl:text>&lt;input</xsl:text>
        </xsl:when>
        <xsl:when test="@type='button'">
          <xsl:text>&lt;h2&gt;button&lt;/h2&gt;</xsl:text>
          <xsl:text>&lt;input type=\"button\"</xsl:text>
        </xsl:when>
      </xsl:choose>
      <xsl:text> id=\"</xsl:text>
      <xsl:value-of select="@id" />
      <xsl:text>\"</xsl:text>
      <xsl:text> value=\"</xsl:text>
      <xsl:value-of select="@label" />
      <xsl:text>\"</xsl:text>
      <xsl:text>&gt;&lt;/input&gt;</xsl:text>

  </xsl:for-each>";
     return formContent;
    }   
   </xsl:for-each>
  }
}

</xsl:template>
</xsl:stylesheet>

This outputs the relevant line as follows:

 string formContent = "<h2>textbox</h2><input id=\"text-14708410685\" value=\"start\"></input><h2>textbox</h2><input id=\"text-5651568987\" value=\"end\"></input><h2>button</h2><input type=\"button\" id=\"button-1470841070721\" value=\"Button\"></input>";

See it in action at http://xsltransform.net/3NSSEuH

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.