2009-07-08 24 views
0

使用this file作爲源,我有一種情況需要從本地源文件或導入中記錄的相關文件中檢索元素。 type值使用冒號分隔兩個值 - substring-before(@type,':')告訴我要引用哪個文件; substring-after(@type,':')是我需要複製&以相同方式遍歷其內容的文件中元素的名稱。XSLT:複製當前類型值等於元素名稱

示例:我想要名稱爲「PersonType」的xs:complexType,因此我使用副本來抓取它及其子項。下一步是查看那些孩子 - 對於那些是xs:element,我想檢索類型值中引用的元素(「AcRec:HighSchoolType」)。 「AcRec」告訴我需要使用哪個xsd,所以我知道我會在xsd中找到名稱值爲「HighSchoolType」的內容。看看AcRec xsd,我知道「HighSchoolType」是一個xs:complexType(我已經定義了一個模板來處理),所以我應該看到輸出。

<?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> 

所需的輸出看起來像:

<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> 

我缺少的是對文檔中尋找時,我順利進入了xsl:什麼時候? xsl:文本告訴我我在,但後面的行不返回任何輸出。

此外,如何排除xs:annotation和xs:restriction元素在複製xs:complextType & xs:simpleType元素時出現?我一直無法獲得dpawson網站上提到的例子。

回答

0

的問題是:

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

...應該是:

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

ScottSEA - 你是正確的,當你說,這是基於比較:

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

會發生什麼事是,有參與該XPath表達式的處理的上下文切換。當你說// * [@ name = substring-after(@type,':')],你會說「將這個模板應用到XSD文檔中被引用的那些元素,它們同時具有@name和@type屬性,並且其@name等於子字符串THEIR @type之後的':'。但是,如果你使用一個變量,你當然會從當前文檔中獲得substring-after。

0

我不得不說,並且不要冒犯你的問題真的很難理解;你能把它分解一點嗎?

同時,儘可能排除XS:註釋和xs:限制元素,只是改變你複製的聲明給他們留下了:

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

...和你有一個的xsl:選擇元素只有一個的xsl:當沒有的xsl:否則 ...你可以用XSL簡化這樣的:如果元素:

<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> 

經過進一步反思,看起來您的select語句可能格式錯誤:當前它試圖匹配具有與冒號後的type屬性匹配的name屬性的任何元素。所以,一場比賽就必須

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

如果你沒有這樣的元素,那麼你的對手是空的,所以沒有模板運行。

+0

我更新了帖子以包含一個例子 - 希望更清楚一點,我沒有任何幸運與您建議的排除 - 是否有兒童與註釋/限制元素相關聯? – 2009-07-08 19:03:44