2016-07-12 9 views
0

Ich verwende XLST 1.0 und möchte Transform XML to add 'nil' attributes to empty elements. Ich finde, dass der Namespace zu jedem passenden Element hinzugefügt wird, wie meine Ausgabe aussieht: Namespace zum Stammknoten hinzufügen, wenn der Stammknoten mehrere Typen haben kann

Ich weiß, das ist gültig, aber ich würde lieber, es wurde zu meinem Top-Knoten hinzugefügt. Ich kam in dieser Antwort: How can I add namespaces to the root element of my XML using XSLT?

Jedoch habe ich mehrere mögliche Wurzelknoten, so dass ich dachte, dass ich etwas tun könnte:

<xsl:template match="animals | people | things"> 
    <xsl:element name="{name()}"> 
     <xsl:attribute name="xmlns:xsi">http://www.w3.org/2001/XMLSchema-instance</xsl:attribute> 
     <xsl:apply-templates/> 
    </xsl:element> 
    </xsl:template> 

Jedoch habe ich einen Fehler von Visual Studio bekommen „prexix Xmlns nicht definiert“ und ich bin mir nicht sicher, was ich dagegen tun soll.

Here is my total XLST file (es so aus irgendeinem Grund fügen Sie werden nicht in), die ein paar Dinge zu tun versucht:

  1. verschiedene Tierarten in einem einzigen Typ
  2. den Namespace auf den Wurzelknoten hinzufügen Trans
  3. hinzufügen xsi:nil = true Elemente zu leeren (beachten sie keine Kinder nicht nur keinen Text haben muss, oder mein Top-Level-Knoten umgewandelt wird)
+0

http://stackoverflow.com/help/be-nice –

Antwort

0

Zuerst wird ein Namen Die Pace-Deklaration ist kein Attribut und kann nicht mit der Anweisung xsl:attribute erstellt werden.

können Sie xsl:copy-of verwenden, um eine Namespace-Deklaration „von Hand“ an einer gewünschten Stelle einfügen, zum Beispiel:

XSLT 1,0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<!-- identity transform --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="/*"> 
    <xsl:copy> 
     <xsl:copy-of select="document('')/xsl:stylesheet/namespace::xsi"/> 
     <xsl:apply-templates/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="*[not(node())]"> 
    <xsl:copy> 
     <xsl:attribute name="xsi:nil">true</xsl:attribute> 
     <xsl:apply-templates/> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

Allerdings sind die Ergebnisse eher prozessorabhängig. Xalan zum Beispiel ignoriert diese Anweisung und wiederholt die Deklaration an jedem leeren Knoten, den es wie zuvor ausgibt. Im Allgemeinen haben Sie kaum Einfluss darauf, wie Ihr XSLT-Prozessor die Ausgabe serialisiert.

Eine weitere Option ist auf der Stammebene Verwendung die Namespace-Deklaration tatsächlich sagen:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<!-- identity transform --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="/*"> 
    <xsl:copy> 
     <xsl:attribute name="xsi:nil">false</xsl:attribute> 
     <xsl:apply-templates/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="*[not(node())]"> 
    <xsl:copy> 
     <xsl:attribute name="xsi:nil">true</xsl:attribute> 
     <xsl:apply-templates/> 
    </xsl:copy> 
</xsl:template> 

</xsl:stylesheet> 

Dies mit allen Prozessoren arbeitete ich mit (YMMV) getestet haben.

Natürlich ist die beste Option, nichts zu tun, da, wie Sie bemerkt haben, der Unterschied rein kosmetisch ist.