tags:

views:

41

answers:

4

Hello,

I'm using an XSLT to transform from one XML standard to another. The particular resulting XML standard contains a root element which is part of a namespace and a child node which is part of another namepsace.

The transform successfully reflects these namespaces but the child's child now contains a blank xmlns attribute. How can I prevent this xmlns=""???

XSLT Snippet:

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

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="@* | node()">
    <xsl:apply-templates select="REQUEST_GROUP" />
  </xsl:template>

  <xsl:template match="REQUEST_GROUP">
    <ONCORE_ERECORD xmlns="http://aptitudesolutions.com"&gt;
      <xsl:apply-templates select="REQUEST/PRIA_REQUEST/PACKAGE"/>
      <PAYMENT PaymentType="ACH" />
     <TRANSACTION_INFO _AgentKey="" _AgentPassword="" />
    </ONCORE_ERECORD>
 </xsl:template>

  <xsl:template match="PACKAGE">
    <DOCUMENT_RECORDATION xmlns="http://pria.org"&gt;
        <xsl:apply-templates select="PRIA_DOCUMENT"/>
    </DOCUMENT_RECORDATION>
  </xsl:template>

  <xsl:template match="PRIA_DOCUMENT">
    <PRIA_DOCUMENT _PRIAVersion="1.2">
      <xsl:attribute name="_Type">
        <xsl:value-of select="@RecordableDocumentType"/>
      </xsl:attribute>
      <xsl:attribute name="_Code"/>

  <xsl:apply-templates select="GRANTOR" />
  <xsl:apply-templates select="GRANTEE" />
  <xsl:choose>
    <xsl:when test="count(PROPERTY) = 0">
      <PROPERTY>
        <xsl:attribute name="_StreetAddress">
          <xsl:value-of select="@StreetAddress"/>
        </xsl:attribute>
        <xsl:attribute name="_StreetAddress2">
          <xsl:value-of select="@StreetAddress2"/>
        </xsl:attribute>
        <xsl:attribute name="_City">
          <xsl:value-of select="@City"/>
        </xsl:attribute>
        <xsl:attribute name="_State">
          <xsl:value-of select="@State"/>
        </xsl:attribute>
        <xsl:attribute name="_PostalCode">
          <xsl:value-of select="@PostalCode"/>
        </xsl:attribute>
        <xsl:attribute name="_County">
          <xsl:value-of select="@County"/>
        </xsl:attribute>
        <xsl:apply-templates select="LEGAL_DESCRIPTION"/>
      </PROPERTY>
    </xsl:when>
    <xsl:otherwise>
      <xsl:apply-templates select="PROPERTY" />
    </xsl:otherwise>
  </xsl:choose>
  <xsl:choose>
    <xsl:when test="count(PARTIES) = 0">
      <PARTIES>
        <_RETURN_TO_PARTY _UnparsedName="" _StreetAddress="" _StreetAddress2="" _City="" _State="" _PostalCode="" />
      </PARTIES>
    </xsl:when>
    <xsl:otherwise>
      <xsl:apply-templates select="PARTIES" />
    </xsl:otherwise>
  </xsl:choose>
  <xsl:apply-templates select="EXECUTION" />
  <xsl:apply-templates select="CONSIDERATION" />
  <xsl:apply-templates select="RECORDABLE_DOCUMENT/_ASSOCIATED_DOCUMENT" />
  <xsl:apply-templates select="EMBEDDED_FILE" />
</PRIA_DOCUMENT>

Source XML:

<REQUEST_GROUP PRIAVersionIdentifier="2.4">
  <REQUEST>
    <PRIA_REQUEST _Type="RecordDocuments">
      <PACKAGE>
        <PRIA_DOCUMENT PRIAVersionIdentifier="2.4" RecordableDocumentSequenceIdentifier="1" RecordableDocumentType="Mortgage">

Resulting XML:

<?xml version="1.0" encoding="utf-8"?>
<ONCORE_ERECORD xmlns="http://aptitudesolutions.com"&gt;
  <DOCUMENT_RECORDATION xmlns="http://pria.org"&gt;
    <PRIA_DOCUMENT _PRIAVersion="1.2" _Type="Mortgage" _Code="" xmlns="">
A: 

This is happening because PRIA_DOCUMENT is in the default namespace, while its parent DOCUMENT_RECORDATION is in a non-default namespace. You must put the PRIA_DOCUMENT in the same namespace as its parent, otherwise the serializer is required to generate xmlns="".

  .
  .
<xsl:template match="PRIA_DOCUMENT">
  <PRIA_DOCUMENT _PRIAVersion="1.2" xmlns="http://pria.org"&gt;
  .
  .
  .

See Michael Kay's "XSLT 2.0 and XPATH 2.0, 4th edition", page 475 where he discusses this exact situation.

Jim Garrison
@Jim Garrison: I think you meant that `PRIA_DOCUMENT` is in no namespace or empty namespace. So the namespace fixup adds the overwriting `xmlns=""`
Alejandro
So how would I approach this fix? I would rather the xmlns attribute not be present for DOCUMENT_RECORDATION children. Is this possible?Is namespace not inherited?
alan
Put the xmlns="http://pria.org" on the xsl:stylesheet element. That way it applies to literal result elements in all templates, except where you use xmlns="http://aptitudesolutions.com" to override it in the template match="REQUEST_GROUP".
Martin Honnen
A: 

I already answered almost the same question yesterday: see my answer to *this question*.

Dimitre Novatchev
I'm sorry but I do not at all understand what is going on in that example. It appears as though it is a blind copy of all elements from one xml to another? Is this is the case, it will not work for me; my end result will be an entirely different element structure than the source xml.
alan
A: 

I found a solution that worked, though it may not have been the most efficient way to achieve the desired results.

I simply changed all literal element declarations to:

</xsl:element>

and declared the namespace. The resulting xslt is as follows:

<xsl:template match="REQUEST_GROUP">
<xsl:element name="ONCORE_ERECORD" namespace="http://aptitudesolutions.com"&gt;
  <xsl:apply-templates select="REQUEST/PRIA_REQUEST/PACKAGE"/>
  <xsl:element name="PAYMENT" namespace="http://aptitudesolutions.com"&gt;
    <xsl:attribute name="PaymentType">
      <xsl:value-of select="'ACH'"/>
    </xsl:attribute>
  </xsl:element>
  <xsl:element name="TRANSACTION_INFO" namespace="http://aptitudesolutions.com"&gt;
    <xsl:attribute name="_AgentKey">
      <xsl:value-of select="''"/>
    </xsl:attribute>
    <xsl:attribute name="_AgentPassword">
      <xsl:value-of select="''"/>
    </xsl:attribute>
  </xsl:element>
</xsl:element>
  </xsl:template>

  <xsl:template match="PACKAGE">
<xsl:element name="DOCUMENT_RECORDATION" namespace="http://pria.org"&gt;
  <xsl:apply-templates select="PRIA_DOCUMENT"/>
</xsl:element>
  </xsl:template>

  <xsl:template match="PRIA_DOCUMENT">
<xsl:element name="PRIA_DOCUMENT" namespace="http://pria.org"&gt;
  <xsl:attribute name="_PRIAVersion">
    <xsl:value-of select="'1.2'"/>
  </xsl:attribute>
  <xsl:attribute name="_Type">
    <xsl:value-of select="@RecordableDocumentType"/>
  </xsl:attribute>
  <xsl:attribute name="_Code"/>

  <xsl:apply-templates select="GRANTOR" />
  <xsl:apply-templates select="GRANTEE" />
  <xsl:choose>
    <xsl:when test="count(PROPERTY) = 0">
        <xsl:element name="PROPERTY" namespace="http://pria.org"&gt;
          <xsl:attribute name="_StreetAddress">
            <xsl:value-of select="@StreetAddress"/>
          </xsl:attribute>
          <xsl:attribute name="_StreetAddress2">
            <xsl:value-of select="@StreetAddress2"/>
          </xsl:attribute>
          <xsl:attribute name="_City">
            <xsl:value-of select="@City"/>
          </xsl:attribute>
          <xsl:attribute name="_State">
            <xsl:value-of select="@State"/>
          </xsl:attribute>
          <xsl:attribute name="_PostalCode">
            <xsl:value-of select="@PostalCode"/>
          </xsl:attribute>
          <xsl:attribute name="_County">
            <xsl:value-of select="@County"/>
          </xsl:attribute>
          <xsl:apply-templates select="LEGAL_DESCRIPTION"/>
        </xsl:element>
    </xsl:when>
    <xsl:otherwise>
      <xsl:apply-templates select="PROPERTY" />
    </xsl:otherwise>
  </xsl:choose>
  <xsl:choose>
    <xsl:when test="count(PARTIES) = 0">
      <xsl:element name="PARTIES" namespace="http://pria.org"&gt;
        <xsl:element name="_RETURN_TO_PARTY" namespace="http://pria.org"&gt;
          <xsl:attribute name="_UnparseName">
            <xsl:value-of select="''"/>
          </xsl:attribute>
          <xsl:attribute name="_StreetAddress">
            <xsl:value-of select="''"/>
          </xsl:attribute>
          <xsl:attribute name="_StreetAddress2">
            <xsl:value-of select="''"/>
          </xsl:attribute>
          <xsl:attribute name="_City">
            <xsl:value-of select="''"/>
          </xsl:attribute>
          <xsl:attribute name="_State">
            <xsl:value-of select="''"/>
          </xsl:attribute>
          <xsl:attribute name="_PostalCode">
            <xsl:value-of select="''"/>
          </xsl:attribute>
        </xsl:element>
      </xsl:element>
    </xsl:when>
    <xsl:otherwise>
      <xsl:apply-templates select="PARTIES" />
    </xsl:otherwise>
  </xsl:choose>
  <xsl:apply-templates select="EXECUTION" />
  <xsl:apply-templates select="CONSIDERATION" />
  <xsl:apply-templates select="RECORDABLE_DOCUMENT/_ASSOCIATED_DOCUMENT" />
  <xsl:apply-templates select="EMBEDDED_FILE" />
    </xsl:element>
  </xsl:template> 
alan
A: 

You're re-defining the default namespace with each of those nodes with the 'xmlns=' declaration. Because the PRIA_DOCUMENT doesn't have a namespace, the output needs to redeclare it as empty, or it would have the same namespace as it's parent. I'd recommend adding in a named namespace to those elements that have one defined, for example:

<pria:DOCUMENT_RECORDATION xmlns:pria="http://pria.org"&gt;

and

<as:ONCORE_ERECORD xmlns:as="http://aptitudesolutions.com"&gt;

With these named namespaces in place, the blank declaration on the PRIA_DOCUMENT element becomes unnecessary, and is not added.

Flynn1179