title: XSLT 1.0 Output Hex 0x1C - 0x1F to Text File
body: <p>I am using xslt version 1.0 to transform an XML file into a text file that is sent to a third party. The third party format requires data fields to be separated with 0x1F (ascii unit separator), groups to be separated with 0x1D (ascii group separator) and records separated with 0x1E (ascii record separator). Use of these within the stylesheet results in the error below.</p>
  
  <blockquote>
    <p>Character ' ', hexadecimal value 0x1D is illegal in XML documents.</p>
  </blockquote>
  
  <p>I am currently using 0x80 through 0x82 from the extended char set, then running the transformation result through a replace function in c# to replace the values I used with the ones I actually needed, but it seems like there should be a better, more efficient way to do this.</p>
  
  <p>Is there a way to output these values to a text file using the style sheet directly?</p>
  
  <h2><strong>Current Stylesheet</strong></h2>
  
  <pre><code>&lt;?xml version="1.0" encoding="us-ascii"?&gt;
  
  &lt;xsl:stylesheet version="1.0"
                  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                  xmlns:asap="http://www.asapnet.org/pmp/4.2/exchange"
                  xmlns:asap-code="http://www.asapnet.org/pmp/4.2/extension/code"
                  xmlns:asap-ext="http://www.asapnet.org/pmp/4.2/extension"
                  xmlns:asap-meta="http://www.asapnet.org/pmp/4.2/extension/meta"
                  xmlns:nc="http://release.niem.gov/niem/niem-core/3.0/"
                  exclude-result-prefixes="asap asap-code asap-ext asap-meta nc"&gt;
  
    &lt;xsl:output method="text" omit-xml-declaration="yes" indent="no" /&gt;
  
    &lt;xsl:variable name="FieldSeparator" select="'&amp;#127;'"/&gt;
    &lt;xsl:variable name="SegmentTerminator" select="'&amp;#128;'"/&gt;
  
  
    &lt;!--MAIN--&gt;
    &lt;xsl:template match="asap:ReportTransmission"&gt;
      &lt;xsl:apply-templates select="asap-meta:TransactionHeader"/&gt;
      &lt;xsl:apply-templates select="asap-meta:InformationSource"/&gt;
      &lt;xsl:apply-templates select="asap-ext:ReportingPharmacy"/&gt;
    &lt;/xsl:template&gt;
  
  
    &lt;!--TRANSACTION HEADER - TH SEGMENT--&gt;
    &lt;xsl:template match="asap-meta:TransactionHeader"&gt;
      &lt;xsl:value-of select="concat(
                    'TH',
                    $FieldSeparator,
                    asap-meta:ReleaseNumberText,
                    $FieldSeparator,
                    asap-meta:ControlNumberText,
                    $FieldSeparator,
                    asap-code:TransactionKindCode,
                    $FieldSeparator,
                    concat(substring(asap-meta:TransactionDate,1,4),substring(asap-meta:TransactionDate,6,2),substring(asap-meta:TransactionDate,9,2)),
                    $FieldSeparator,
                    concat(substring(asap-meta:TransactionTime,1,2),substring(asap-meta:TransactionTime,4,2)),
                    $FieldSeparator,
                    asap-code:FileKindCode,
                    $FieldSeparator,
                    asap-meta:RoutingNumber,
                    $FieldSeparator,
                    $SegmentTerminator,
                    $SegmentTerminator)" /&gt;
    &lt;/xsl:template&gt;
  
  
    &lt;!--INFORMATION SOURCE - IS SEGMENT--&gt;
    &lt;xsl:template match="asap-meta:InformationSource"&gt;
          &lt;xsl:value-of select="concat(
                    'IS',
                    $FieldSeparator,
                    nc:Identification/nc:IdentificationID,
                    $FieldSeparator,
                    nc:Identification/nc:IdentificationJurisdiction/nc:JurisdictionText,
                    $FieldSeparator,
                    nc:MessageText,
                    $SegmentTerminator)" /&gt;
  
    &lt;/xsl:template&gt;
  &lt;/xsl:stylesheet&gt;
  </code></pre>
  
  <p>(... style sheet continues with additional segments ... )    </p>
  
  <h2><strong>Current Output (Notepad++)</strong></h2>
  
  <p><a href="https://i.stack.imgur.com/DQYcv.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/DQYcv.png" alt="enter image description here"></a></p>
  
  <p>(... output continues with additional segments ... )    </p>
  
  <h2><strong>XML Sample</strong></h2>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;asap:ReportTransmission xmlns:asap="http://www.asapnet.org/pmp/4.2/exchange"
   xmlns:asap-code="http://www.asapnet.org/pmp/4.2/extension/code"
   xmlns:asap-ext="http://www.asapnet.org/pmp/4.2/extension"
   xmlns:asap-meta="http://www.asapnet.org/pmp/4.2/extension/meta"
   xmlns:nc="http://release.niem.gov/niem/niem-core/3.0/" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.asapnet.org/pmp/4.2/exchange ../schemas/exchange/pmp_exchange.xsd"&gt;
      &lt;asap-meta:TransactionHeader&gt;
          &lt;asap-meta:ReleaseNumberText&gt;4.2&lt;/asap-meta:ReleaseNumberText&gt;
          &lt;asap-meta:ControlNumberText&gt;857463&lt;/asap-meta:ControlNumberText&gt;
          &lt;asap-code:TransactionKindCode&gt;01&lt;/asap-code:TransactionKindCode&gt;
          &lt;asap-meta:TransactionDate&gt;2009-10-15&lt;/asap-meta:TransactionDate&gt;
          &lt;asap-meta:TransactionTime&gt;10:45:00&lt;/asap-meta:TransactionTime&gt;
          &lt;asap-code:FileKindCode&gt;P&lt;/asap-code:FileKindCode&gt;
      &lt;/asap-meta:TransactionHeader&gt;
      &lt;asap-meta:InformationSource&gt;
          &lt;nc:Identification&gt;
              &lt;nc:IdentificationID&gt;7564&lt;/nc:IdentificationID&gt;
              &lt;nc:IdentificationJurisdiction&gt;
                  &lt;nc:JurisdictionText&gt;ACME PHARMACY&lt;/nc:JurisdictionText&gt;
              &lt;/nc:IdentificationJurisdiction&gt;
          &lt;/nc:Identification&gt;
      &lt;/asap-meta:InformationSource&gt;
      &lt;asap-ext:ReportingPharmacy&gt;
          &lt;asap-ext:NPIIdentification&gt;
              &lt;nc:IdentificationID&gt;1234567890&lt;/nc:IdentificationID&gt;
          &lt;/asap-ext:NPIIdentification&gt;
          &lt;asap-ext:PatientInfo&gt;
              &lt;nc:PersonBirthDate&gt;
                  &lt;nc:Date&gt;1950-01-01&lt;/nc:Date&gt;
              &lt;/nc:PersonBirthDate&gt;
              &lt;nc:PersonName&gt;
                  &lt;nc:PersonGivenName&gt;John&lt;/nc:PersonGivenName&gt;
                  &lt;nc:PersonSurName&gt;Smith&lt;/nc:PersonSurName&gt;
              &lt;/nc:PersonName&gt;
              &lt;nc:PersonSexText&gt;Male&lt;/nc:PersonSexText&gt;
              &lt;asap-ext:PrimaryIdentification&gt;
                  &lt;nc:PersonLicenseIdentification&gt;
                      &lt;nc:IdentificationID&gt;987544&lt;/nc:IdentificationID&gt;
                      &lt;nc:IdentificationJurisdiction&gt;
                          &lt;nc:LocationStateUSPostalServiceCode&gt;MA&lt;/nc:LocationStateUSPostalServiceCode&gt;
                      &lt;/nc:IdentificationJurisdiction&gt;
                  &lt;/nc:PersonLicenseIdentification&gt;
              &lt;/asap-ext:PrimaryIdentification&gt;
              &lt;nc:ContactMailingAddress&gt;
                  &lt;nc:LocationStreet&gt;
                      &lt;nc:StreetName&gt;1234 Main St&lt;/nc:StreetName&gt;
                  &lt;/nc:LocationStreet&gt;
                  &lt;nc:LocationCityName&gt;Somewhere&lt;/nc:LocationCityName&gt;
                  &lt;nc:LocationStateUSPostalServiceCode&gt;MA&lt;/nc:LocationStateUSPostalServiceCode&gt;
                  &lt;nc:LocationPostalCode&gt;54356&lt;/nc:LocationPostalCode&gt;
              &lt;/nc:ContactMailingAddress&gt;
              &lt;asap-ext:DispensingRecord&gt;
                  &lt;asap-code:ReportingStatusCode&gt;00&lt;/asap-code:ReportingStatusCode&gt;
                  &lt;asap-ext:Prescription&gt;
                      &lt;asap-ext:PrescriptionNumberText&gt;6542984&lt;/asap-ext:PrescriptionNumberText&gt;
                      &lt;asap-ext:PrescriptionWrittenDate&gt;
                          &lt;nc:Date&gt;2009-10-15&lt;/nc:Date&gt;
                      &lt;/asap-ext:PrescriptionWrittenDate&gt;
                      &lt;asap-ext:PrescriptionRefillQuantity&gt;0&lt;/asap-ext:PrescriptionRefillQuantity&gt;
                      &lt;asap-ext:ProductIdentification&gt;
                          &lt;nc:IdentificationID&gt;57866707401&lt;/nc:IdentificationID&gt;
                          &lt;asap-code:ProductIdentifierKindCode&gt;01&lt;/asap-code:ProductIdentifierKindCode&gt;
                      &lt;/asap-ext:ProductIdentification&gt;
                      &lt;asap-ext:PrescriptionSupplyQuantity&gt;15&lt;/asap-ext:PrescriptionSupplyQuantity&gt;
                  &lt;/asap-ext:Prescription&gt;
                  &lt;asap-ext:Transaction&gt;
                      &lt;asap-ext:PrescriptionFilledDate&gt;
                          &lt;nc:Date&gt;2009-10-15&lt;/nc:Date&gt;
                      &lt;/asap-ext:PrescriptionFilledDate&gt;
                      &lt;asap-ext:PrescriptionRefillNumber&gt;0&lt;/asap-ext:PrescriptionRefillNumber&gt;
                      &lt;asap-ext:PrescriptionDispensedQuantity&gt;30&lt;/asap-ext:PrescriptionDispensedQuantity&gt;
                  &lt;/asap-ext:Transaction&gt;
                  &lt;asap-ext:Prescriber&gt;
                      &lt;asap-ext:DEAIdentification&gt;
                          &lt;nc:IdentificationID&gt;AW8765432&lt;/nc:IdentificationID&gt;
                      &lt;/asap-ext:DEAIdentification&gt;
                  &lt;/asap-ext:Prescriber&gt;          
                  &lt;asap-ext:AdditionalInformation&gt;
                      &lt;asap-ext:IssuingPrescriptionBlankIdentification&gt;
                          &lt;nc:IdentificationID&gt;787456493993&lt;/nc:IdentificationID&gt;
                          &lt;nc:IdentificationJurisdiction&gt;
                              &lt;nc:LocationStateUSPostalServiceCode&gt;MA&lt;/nc:LocationStateUSPostalServiceCode&gt;
                          &lt;/nc:IdentificationJurisdiction&gt;
                      &lt;/asap-ext:IssuingPrescriptionBlankIdentification&gt;
                  &lt;/asap-ext:AdditionalInformation&gt;
              &lt;/asap-ext:DispensingRecord&gt;
          &lt;/asap-ext:PatientInfo&gt;
      &lt;/asap-ext:ReportingPharmacy&gt;
  &lt;/asap:ReportTransmission&gt;
  </code></pre>
  
  <hr>
  
  <h2>Update</h2>
  
  <hr>
  
  <p>For those who may be looking for a similar solution, I ended up going with a C# script within the stylesheet.</p>
  
  <pre><code>  &lt;msxsl:script implements-prefix="CSharpScripts" language="C#"&gt;
      public string FS()
      {
      return '\u001F'.ToString();
      }
  
      public string GS()
      {
      return '\u001D'.ToString();
      }
    &lt;/msxsl:script&gt;
  </code></pre>
  
  <p>It can then be used like this:</p>
  
  <pre><code>&lt;xsl:value-of select="CSharpScripts:FS()"/&gt;
  </code></pre>
  
  <p>You do need to set <em>EnableScript = true</em> using <em>XsltSettings</em> when loading the <em>XslCompiledTransform</em>, and set <em>CheckCharacters = false</em> on the <em>XmlWriter</em> being used for output:</p>
  
  <pre><code>            var xslt = new XslCompiledTransform();
              xslt.Load(
                      @"E:\TFS\Transforms\TestTransform.xslt",
                      new XsltSettings() {EnableScript = true}, null);
  
              var writerSettings = xslt.OutputSettings.Clone();
              writerSettings.CheckCharacters = false;
  
              var sb = new StringBuilder();
  
              var xmlOutput = XmlWriter.Create(sb, writerSettings);
  
              xslt.Transform(@"E:\samples.xml", xmlOutput);
  </code></pre>
  
  <p>Thanks to @Abel for pointing me in the right direction.</p>