2010-08-17 4 views
15

Ich verwende eine XSLT, um von einem XML-Standard zum anderen zu transformieren. Der bestimmte resultierende XML-Standard enthält ein Wurzelelement, das Teil eines Namensraums ist, und einen Kindknoten, der Teil eines anderen Namensraums ist.XSLT blank xmlns = "" nach der Transformation

Die Transformation spiegelt diese Namespaces erfolgreich wider, aber das untergeordnete Kind enthält jetzt ein leeres xmlns-Attribut. Wie kann ich das verhindern 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://test.com"> 
     <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://test2.org"> 
     <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> 

Quelle XML:

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

resultierenden XML-:

<?xml version="1.0" encoding="utf-8"?> 
<ONCORE_ERECORD xmlns="http://test.com"> 
    <DOCUMENT_RECORDATION xmlns="http://test2.org"> 
    <PRIA_DOCUMENT _PRIAVersion="1.2" _Type="Mortgage" _Code="" xmlns=""> 
+0

könnten Sie bitte, geben Sie das (möglichst kleine) XML-Dokument, auf das der XSLT-Stylesheet das bereitgestellte Ergebnis führt? –

+0

Ich habe das oben angefragte XML als "Source XML:" – alan

+0

hinzugefügt. Ich habe bereits gestern fast die gleiche Frage beantwortet: ** Siehe meine Antwort auf ** ** [diese Frage] (http://stackoverflow.com/questions/3490246/ problem-mit-hinzufügen-Xmlns-Attribut-zu-Xml-Dokument-Using-Xsl) **. –

Antwort

5

Ich fand eine Lösung, die funktionierte, obwohl es möglicherweise nicht der effizienteste Weg war, um die gewünschten Ergebnisse zu erzielen.

änderte ich einfach alle Literalelement Erklärungen:

</xsl:element> 

und den Namespace deklariert. Das resultierende Xslt ist wie folgt:

<xsl:template match="REQUEST_GROUP"> 
<xsl:element name="ONCORE_ERECORD" namespace="http://test.com"> 
    <xsl:apply-templates select="REQUEST/PRIA_REQUEST/PACKAGE"/> 
    <xsl:element name="PAYMENT" namespace="http://test.com"> 
    <xsl:attribute name="PaymentType"> 
     <xsl:value-of select="'ACH'"/> 
    </xsl:attribute> 
    </xsl:element> 
    <xsl:element name="TRANSACTION_INFO" namespace="http://test.com"> 
    <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://test2.org"> 
    <xsl:apply-templates select="PRIA_DOCUMENT"/> 
</xsl:element> 
    </xsl:template> 

    <xsl:template match="PRIA_DOCUMENT"> 
<xsl:element name="PRIA_DOCUMENT" namespace="http://test2.org"> 
    <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://test2.org"> 
      <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://test2.org"> 
     <xsl:element name="_RETURN_TO_PARTY" namespace="http://test2.org"> 
      <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> 
6

Dies geschieht, weil PRIA_DOCUMENT im Standard-Namespace ist, während seine pa Miete DOCUMENT_RECORDATION befindet sich in einem nicht standardmäßigen Namespace. Sie müssen PRIA_DOCUMENT im selben Namespace wie das übergeordnete Element platzieren, andernfalls muss der Serializer xmlns="" generieren.

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

Siehe Michael Kay "XSLT 2.0 und XPath 2.0, 4. Auflage", Seite 475, wo er genau diese Situation diskutiert.

+0

Ich glaube, Sie meinten, dass 'PRIA_DOCUMENT' in keinem Namespace oder leeren Namespace ist. Also fügt der Namespace fixup das Überschreiben hinzu 'xmlns =" ​​"' –

+0

Also, wie würde ich dieses Update angehen? Ich würde lieber das Xmlns-Attribut nicht für DOCUMENT_RECORDATION Kinder vorhanden sein. Ist das möglich? Wird der Namespace nicht vererbt? – alan

+2

Setzen Sie die xmlns = "http://pria.org" auf das xsl: stylesheet -Element. Auf diese Weise gilt es für literale Ergebniselemente in allen Vorlagen, außer wenn Sie xmlns = "http://aptitudesolutions.com" verwenden, um sie in der Vorlage match = "REQUEST_GROUP" zu überschreiben. –

0

Sie sind neu zu definieren den Standard-Namespace mit jeder dieser Knoten mit der Deklaration ‚xmlns =‘. Da der PRIA_DOCUMENT keinen Namespace hat, muss die Ausgabe ihn als leer deklarieren, oder er hätte den gleichen Namespace wie der übergeordnete Namespace. Ich würde empfehlen, in einem benannten Namespace auf jene Elemente hinzufügen, die man definiert, zum Beispiel haben:

<pria:DOCUMENT_RECORDATION xmlns:pria="http://pria.org">

und

<as:ONCORE_ERECORD xmlns:as="http://aptitudesolutions.com">

Mit diesem Namen Namensraum vorhanden, wird die leere Erklärung Das Element PRIA_DOCUMENT wird unnötig und wird nicht hinzugefügt.

3

Legen Sie die aufrufende Vorlage und die angewandte Vorlage in den gleichen Namespace.

1

Ich war sogar ein ähnliches Problem mit dem Namensraum für die untergeordneten Elemente erklärt, aber noch wurde Ende mit

xmlns="" 

Ich dachte, es auf die XSLT-Transformation zurückzuführen war, aber die Saite Ergebnis der Transformation war richtig und Es war, als ich dann die Zeichenkette in ein org.w3c.dom.Document verwandelte, dass die Standardnamensräume hinzugefügt wurden.

Making the Documentnamespace bewusst fixiert diesen

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
dbf.setNamespaceAware(true); 
DocumentBuilder db = dbf.newDocumentBuilder(); 
Document metadataDOM = db.parse(new ByteArrayInputStream(stringWriter.toString().getBytes())); 
+0

Danke Dan675. In meiner Anwendung haben wir uns auch mit diesem Problem konfrontiert und jetzt wird es gelöst, indem Sie Ihrem Ansatz folgen, um den Namensraum bewusst zu machen. – joy