2009-09-18 10 views
0

Fondamentalement, je veux une copie exacte du XML, sauf que je voudrais trier certains noeuds par leur attribut ID. Tous les éléments avec l'attribut ID ne doivent pas être triés.Tri XML générique via XSLT appliqué par Java?

J'ai collé ensemble une feuille de style de travail, mais cela nécessite de coder en dur les < xsl: apply-template > pour tous les noeuds frères aux noeuds sur lesquels je trie. Je n'ai pas de schéma formel, et je ne peux pas être certain que cela ne changera pas. J'aimerais pouvoir créer une feuille de style plus générique qui produira les noeuds non triés sans ces appels explicites.

Est-ce possible?

Mon code Java pour transformer le XML:

String input = "C:\\presort.xml"; 
String output = "C:\\postsort.xml"; 
String xsl = "C:\\sort.xsl" 
Document dom; 

try 
{ 
dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(input); 
Element e = dom.getDocumentElement(); 

Transformer transform = TransformerFactory.newInstance().newTransformer(
    new StreamSource(new File(xsl))); 
StreamResult result = new StreamResult(new File(output)); 
transform.transform(new DOMSource(dom), result); 
} 
catch (Exception e) 
{ 
e.printStackTrace(); 
}  

Mon XML:

<?xml version="1.0" encoding="utf-8"?> 
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 

    <Person id="1"> 
    <Base>true</Base> 
    <Description>something</Description> 
    <Name>Vin Vinigar</Name> 
    <Privileges> 
     <Privilige id="340"> 
     <Permission>2</Permission> 
     <Job id="dontsort" /> 
     </Privilige> 
     <Privilige id="11"> 
     <Permission>3</Permission> 
     <Job id="dontsort" /> 
     </Privilige> 
     <Privilige id="1011"> 
     <Permission>1</Permission> 
     <Job id="2342" /> 
     </Privilige> 
    </Privileges> 
    </Person> 

    <Person id="f32"> 
    <Base>true</Base> 
    <Description>Here be dragons</Description> 
    <Name>John Doe</Name> 
    <Privileges> 
     <Privilige id="23a"> 
     <Permission>2</Permission> 
     <Job id="a2a" /> 
     </Privilige> 
    </Privileges> 
    </Person> 

    <Person id="22"> 
    <PossibleUnknownTagHere>something</PossibleUnknownTagHere> 
    <Name>Han Solo</Name> 
    <Privileges> 
     <Privilige id="23a"> 
     <Permission>3</Permission> 
     <Job id="a2a" /> 
     </Privilige> 
    </Privileges> 
    </Person> 

</root> 

Mon style:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:template match="root|@*"> 
     <xsl:copy > 
      <xsl:apply-templates select="@*" /> 
      <xsl:apply-templates select="Person"> 
       <xsl:sort select="@id" order="ascending" /> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Person"> 
     <xsl:copy > 
      <xsl:apply-templates select="@*" /> 

      <!-- Works but requies a template for each sibling element --> 
      <xsl:apply-templates select="Base" /> 
      <xsl:apply-templates select="Description" /> 
      <xsl:apply-templates select="Name" /> 

      <!-- I'd like to do something like this --> 
      <!-- 
      <xsl:choose> 
       <xsl:when test="not(Privileges)"> 
        <xsl:apply-templates select="." /> 
       </xsl:when> 
      </xsl:choose> 
      --> 

      <xsl:apply-templates select="Privileges" /> 
     </xsl:copy> 
    </xsl:template> 

    <!-- I'd like to remove the need for these 3 explicity copies --> 
    <xsl:template match="Base"> 
     <xsl:copy-of select="."/> 
    </xsl:template> 
    <xsl:template match="Description"> 
     <xsl:copy-of select="."/> 
    </xsl:template> 
    <xsl:template match="Name"> 
     <xsl:copy-of select="."/> 
    </xsl:template> 

    <xsl:template match="Privileges"> 
     <xsl:copy > 
      <xsl:apply-templates select="@*" /> 
      <xsl:apply-templates select="Privilege"> 
       <xsl:sort select="@id" order="ascending" /> 
      </xsl:apply-templates> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Privilege"> 
     <xsl:copy-of select="."/> 
    </xsl:template> 

</xsl:stylesheet> 

Répondre

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

<xsl:template match="root"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*" /> 
     <xsl:apply-templates select="Person"> 
      <xsl:sort select="@id" order="ascending" /> 
     </xsl:apply-templates> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="Privileges"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*" /> 
     <xsl:apply-templates select="Privilege"> 
      <xsl:sort select="@id" order="ascending" /> 
     </xsl:apply-templates> 
    </xsl:copy> 
</xsl:template> 
+0

Malheureusement, cela ne copie pas les attributs sur les nœuds qui ont été triés. – jhsheets

+0

Hmm, je dois avoir incorrectement copié le XSL car il fonctionne maintenant. Merci :) – jhsheets