简体   繁体   中英

Adding a namespace when transforming XML using XSL

I am trying to use a XSL stylesheet to convert the Source.xml file to the Desired.xml format using the Transform.xsl file. I managed to transform it correctly except the namespace attribute in the node. Does anyone know what I need to put into the xsl transform file to add that attribute?

Desired.xml

<?xml version="1.0"?>
<XML_FAX_SUBMIT java="0" xmlns="x-schema:C:\rf\XML_FAX_SUBMIT_schema.xml" stylesheet="C:\rf\XML_FAX_SUBMIT.XSL">
  <SENDER>
    <FROM_NAME>John Public</FROM_NAME>
    <RF_USER>JOHN</RF_USER>
  </SENDER>
  <DESTINATIONS>
    <FAX unique_id="1">
      <TO_FAXNUM>1234</TO_FAXNUM>
      <TO_NAME>Public</TO_NAME>
      <TO_COMPANY>ACME</TO_COMPANY>
      <NOTIFY_HOST SuccessTemplate="1.inc" FailureTemplate="2.inc" Name="NotifyImportServer"/>
    </FAX>
  </DESTINATIONS>
  <ATTACHMENT>
    <FILE path="c:\test\test.tif"/>
  </ATTACHMENT>
</XML_FAX_SUBMIT>

Source.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<DrivveImage>
  <Documents>
    <Document Profile="Test" Profile-ID="0xA84E80AD7068B048B1B99E12E258F1B3" File="test.tif" Destination="C:\test" ImageFilePath="C:\test\test.tif" Pages="1">
      <Fields>        
        <Field Name="FROM_NAME">John Public</Field>
        <Field Name="RF_USER">JOHN</Field>
        <Field Name="TO_FAXNUM">1234</Field>
        <Field Name="TO_NAME">Public</Field>
        <Field Name="TO_COMPANY">ACME</Field>
        <Field Name="UNIQUE_ID">1</Field>
       </Fields>
    </Document>
  </Documents>
</DrivveImage>

Transform.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" encoding="UTF-8" media-type="text/xml" indent="yes"/>
    <xsl:template match="/DrivveImage/Documents/Document">
        <xsl:element name="XML_FAX_SUBMIT">
            <xsl:attribute name="stylesheet">
                <xsl:value-of select="string('C:\RF\XML_FAX_SUBMIT.XSL')"/>
            </xsl:attribute>
            <xsl:attribute name="java">
                <xsl:value-of select="0"/>
            </xsl:attribute> 
            <SENDER>      
                <FROM_NAME>
                    <xsl:value-of select="Fields/Field[@Name='FROM_NAME']"/>
                </FROM_NAME>
                <RF_USER>
                    <xsl:value-of select="Fields/Field[@Name='RF_USER']"/>
                </RF_USER>
            </SENDER>
            <DESTINATIONS>        
                <FAX>
                    <xsl:attribute name="unique_id">
                        <xsl:value-of select="Fields/Field[@Name='UNIQUE_ID']"/>
                    </xsl:attribute>         
                    <TO_FAXNUM>
                        <xsl:value-of select="Fields/Field[@Name='TO_FAXNUM']"/>
                    </TO_FAXNUM>
                    <TO_NAME>
                        <xsl:value-of select="Fields/Field[@Name='TO_NAME']"/>
                    </TO_NAME>
                    <TO_COMPANY>
                        <xsl:value-of select="Fields/Field[@Name='TO_COMPANY']"/>
                    </TO_COMPANY>
                    <NOTIFY_HOST SuccessTemplate="1.inc" FailureTemplate="1.inc" Name="NotifyImportServer" />
                </FAX>
            </DESTINATIONS>
            <xsl:element name="ATTACHMENT"> 
                <FILE>
                    <xsl:attribute name="path"><xsl:value-of select="@Destination"/>\<xsl:value-of select="@File"/></xsl:attribute>
                </FILE>
            </xsl:element>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Thanks in advance.

Strictly speaking, it is not a namespace attribute, but a namespace declaration. You are declaring that all elements within your desired XML are part of this namespace. However, in your source XML, there is no namespace declaration, and so none of the source elements are in a namespace. Furthermore, there is no reference to the namespace in the XSLT, and so as a result your current output has no namespaces.

What you need to do is ensure that the elements you output in your XSLT belong to the namespace your require. You can do use by using the namespace attribute on the xsl:element command used to create the root XML_FAX_SUBMIT element:

<xsl:element name="XML_FAX_SUBMIT" namespace="x-schema:C:\rf\XML_FAX_SUBMIT_schema.xml">

However, when used in this way it will only set the namespace of the specified element. You will also need to set this on the SENDER and DESTINATIONS element, for example

<SENDER xmlns="x-schema:C:\rf\XML_FAX_SUBMIT_schema.xml">

<DESTINATIONS xmlns="x-schema:C:\rf\XML_FAX_SUBMIT_schema.xml">

Doing it this way means all the child elements belong to the same namespace too.

Infact, it would be easier if you created XML_FAX_SUBMIT element in this way

<XML_FAX_SUBMIT xmlns="x-schema:C:\rf\XML_FAX_SUBMIT_schema.xml">

Then you would only have to add the namespace declaration in one place.

Try the following XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" encoding="UTF-8" media-type="text/xml" indent="yes"/>
  <xsl:template match="/DrivveImage/Documents/Document">
    <XML_FAX_SUBMIT xmlns="x-schema:C:\rf\XML_FAX_SUBMIT_schema.xml" stylesheet="{string('C:\RF\XML_FAX_SUBMIT.XSL')}" java="0">
      <xsl:attribute name="stylesheet">
        <xsl:value-of select="string('C:\RF\XML_FAX_SUBMIT.XSL')"/>
      </xsl:attribute>
      <xsl:attribute name="java">
        <xsl:value-of select="0"/>
      </xsl:attribute>
      <SENDER>
        <FROM_NAME>
          <xsl:value-of select="Fields/Field[@Name='FROM_NAME']"/>
        </FROM_NAME>
        <RF_USER>
          <xsl:value-of select="Fields/Field[@Name='RF_USER']"/>
        </RF_USER>
      </SENDER>
      <DESTINATIONS>
        <FAX unique_id="{Fields/Field[@Name='UNIQUE_ID']}">
          <TO_FAXNUM>
            <xsl:value-of select="Fields/Field[@Name='TO_FAXNUM']"/>
          </TO_FAXNUM>
          <TO_NAME>
            <xsl:value-of select="Fields/Field[@Name='TO_NAME']"/>
          </TO_NAME>
          <TO_COMPANY>
            <xsl:value-of select="Fields/Field[@Name='TO_COMPANY']"/>
          </TO_COMPANY>
          <NOTIFY_HOST SuccessTemplate="1.inc" FailureTemplate="1.inc" Name="NotifyImportServer" />
        </FAX>
      </DESTINATIONS>
      <ATTACHMENT>
        <FILE path="{@Destination}\{@File}">
        </FILE>
      </ATTACHMENT>
    </XML_FAX_SUBMIT>
  </xsl:template>
</xsl:stylesheet>

Also note the use of "Attribute Value Templates" to set the attributes, instead of xsl:attribute . Where you see curly braces { } in an attribute, this indicates an expression to be evaluated, as opposed output literally.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM