2009-07-08 6 views
0

En utilisant this file comme source, j'ai une situation où j'ai besoin de récupérer un élément du fichier source local ou un élément connexe noté dans les importations. La valeur de type utilise un deux-points pour séparer les deux valeurs - substring-before (@type, ':') me dit quel fichier à référencer; substring-after (@type, ':') est le nom de l'élément dans le fichier que j'ai besoin de copier & itérer sur son contenu de la même manière.XSLT: Copie Lorsque la valeur du type courant est égale au nom d'un élément

Exemple: Je veux le xs: complexType où le nom est "PersonType", donc j'utilise le copy-of pour l'attraper et ses enfants. L'étape suivante consiste à regarder ces enfants - pour ceux qui sont xs: element, je veux récupérer l'élément référencé dans la valeur du type ("AcRec: HighSchoolType"). Le "AcRec" me dit quel xsd je dois utiliser, donc je sais que je trouverai quelque chose dans ce xsd où la valeur du nom est "HighSchoolType". En regardant le xsd AcRec, je sais que "HighSchoolType" est un xs: complexType (que j'ai déjà un modèle défini pour gérer), donc je devrais voir la sortie.

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xsl:template match="/"> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:core="urn:org:pesc:core:CoreMain:v1.2.0" xmlns:AcRec="urn:org:pesc:sector:AcademicRecord:v1.1.0"> 
    <xsl:apply-templates select="//xs:complexType[@name='PersonType']" />  
</xs:schema> 
</xsl:template> 

<xsl:template match="xs:complexType"> 
    <xsl:copy> 
     <xsl:copy-of select="node()[not(xs:annotation | xs:restriction)]|@*"/> 
    </xsl:copy> 
    <xsl:apply-templates select=".//xs:element" /> 
</xsl:template> 

<xsl:template match="xs:simpleType"> 
    <xsl:copy> 
     <xsl:copy-of select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="xs:element"> 
    <xsl:choose> 
     <xsl:when test="substring-before(@type, ':') = 'AcRec'"> 
      <xsl:text>AcRec</xsl:text> 
      <xsl:apply-templates select="document('[local file path]AcademicRecord_v1.3.0.xsd')//*[@name=substring-after(@type, ':')]" /> 
     </xsl:when>      
    </xsl:choose> 
</xsl:template> 

sortie désiré ressemblerait à ceci:

<xs:complexType name="PersonType"> 
    <xs:sequence> 
    <xs:element name="HighSchool" type="AcRec:HighSchoolType" minOccurs="0"> 
    </xs:sequence> 
</xs:complexType> 
<xs:complexType name="HighSchoolType"> 
    <xs:sequence> 
    <xs:element name="OrganizationName" type="core:OrganizationNameType"/> 
    <xs:group ref="core:OrganizationIDGroup" minOccurs="0"/> 
    </xs:sequence> 
</xs:complexType> 

Qu'est-ce que je manque sur la recherche dans le document quand je réussi à entrer sur le xsl: quand? Le texte xsl: me dit que je suis dedans, mais la ligne suivante ne renvoie aucune sortie.

De plus, comment exclure xs: annotation et xs: des éléments de restriction n'apparaissent lors de la copie de xs: complextType & xs: simpleType elements? Je n'ai pas réussi à faire fonctionner les exemples mentionnés sur le site dpawson.

Répondre

0

La question était:

<xsl:apply-templates select="document('[local file path]AcademicRecord_v1.3.0.xsd')//*[@name=substring-after(@type, ':')]" /> 

...devrait être:

<xsl:variable name="name" select="substring-after(@type, ':')" /> 
<xsl:apply-templates select="document('[local file path]AcademicRecord_v1.3.0.xsd')//*[@name=$name]" /> 

ScottSEA - vous aviez raison quand vous avez dit qu'il comparait basé sur:

<element name="text" type="some:text"/> 

Ce qui se passe est qu'il ya un changement de contexte impliqué dans le traitement de cette expression XPath. Quand vous dites // * [@ name = substring-after (@type, ':')], vous dites "appliquer ce modèle aux éléments du document XSD référencé, qui ont à la fois un attribut @name et un attribut @type, et dont @name est égal à substring-after ':' de THEIR @type Alors que, si vous utilisez une variable, vous obtenez bien sûr la sous-chaîne du document courant

0

Je dois dire, et ne vous offusquez pas, que votre question est vraiment difficile à comprendre; pourriez-vous le décomposer un peu plus?

Pendant ce temps, jusqu'à l'exclusion xs: annotation et xs: éléments de restriction, il suffit de modifier votre copie de déclaration à les laisser:

<xsl:copy-of select="node()[not(self::xs:annotation or self::xs:restriction)]|@*"/> 

... et vous avez une xsl: choose avec un seul élément xsl: when et pas xsl: autrement ... vous pourriez simplifier avec un élément xsl: if:

<xsl:template match="xs:element"> 
    <xsl:if test="substring-before(@type, ':') = 'AcRec'"> 
    <xsl:text>AcRec</xsl:text> 
     <xsl:apply-templates select="document('[local file path]AcademicRecord_v1.3.0.xsd')//*[@name=substring-after(@type, ':')]" /> 
    </xsl:if> 
</xsl:template> 

Après réflexion, il semblerait que votre instruction select soit mal formée: actuellement, elle essaie de faire correspondre tout élément ayant un attribut name qui correspond à l'attribut type après le signe deux-points. Donc, un match devrait être

<element name="text" type="some:text"/> 

Si vous ne disposez pas d'un élément comme celui-ci, votre match est vide, donc pas de modèles sont exécutés.

+0

J'ai mis à jour le post pour inclure un exemple - j'espère que c'est plus clair, je n'ai pas eu de chance avec l'exclusion que vous avez suggérée - est-ce que cela aurait de l'importance s'il y avait des enfants associés aux annotations/restrictions? –

+0

Je préfère que ça corresponde à que . J'ai interprété le CHOOSE pour attraper les différentes instances de "some" dans le courant afin que je sache utiliser some.xsd pour chercher l'élément name = " texte ". –

+0

ouais ... j'ai oublié l'auto :: axis dans l'annotation/segment de restriction. Révisé de manière appropriée. –

Questions connexes