2011-12-23 65 views
1

我在下面的圖案自動創建XML模板基於字符串模式使用XSLT

筆者〜時間〜assignedAuthor〜assignedAuthor/ID〜assignedAuthor /地址〜assignedAuthor /電信〜assignedAuthor/assignedPerson /名〜

所有的第一個元素是根的時間(在上述字符串模式是作者)和它們的其餘都是用字符「〜」 delemeted子元素。我想通過使用上面的字符串模式使用XSLT 2.0創建XML,並且我想在下面生成XML。

<author> 
    <time/> 
    <assignedAuthor> 
     <id/> 
     <addr/> 
     <telecom/> 
     <assignedPerson> 
      <name/> 
     </assignedPerson> 
    </assignedAuthor> 
</author> 

我可以爲此提供可能的解決方案。

+0

爲什麼'author〜time',而是'assignedAuthor〜assignedAuthor/id'?換句話說,爲什麼'assignedAuthor'重複了,但'author'不是?不應該是'author〜author/time〜author/assignedAuthor〜...' – khachik 2011-12-23 20:01:58

+3

我想用VBScript把有毒廢物變成快樂的小貓。 – Filburt 2011-12-23 20:10:41

+0

正如我上面指出的那樣,作者是一個適用於所有元素上下文的根元素。 – 2011-12-23 20:22:31

回答

3

該轉化

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:my="my:my" exclude-result-prefixes="my xs"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:variable name="vSegments" select= 
    "tokenize(translate(/*, ' &#9;&#xA;&#xD;', ''), 
      '~') 
       [.] 
    "/> 

    <xsl:template match="/*"> 
    <xsl:sequence select="my:buildXml($vSegments)"/> 
    </xsl:template> 

<xsl:function name="my:buildXml"> 
    <xsl:param name="pSegments" as="xs:string*"/> 

    <xsl:element name="{$pSegments[1]}"> 
    <xsl:sequence select="my:buildXml2($pSegments[position() >1])"/> 
    </xsl:element> 
</xsl:function> 

<xsl:function name="my:buildXml2"> 
    <xsl:param name="pSegments" as="xs:string*"/> 

    <xsl:for-each-group select="$pSegments" 
     group-adjacent="substring-before(concat(.,'/'),'/')"> 
    <xsl:element name="{current-grouping-key()}"> 
     <xsl:variable name="vsubSegments" select= 
     "for $subSeg in current-group(), 
      $subSeqTail in substring-after($subSeg, '/') 
      return 
      $subSeqTail[.] 
     "/> 
     <xsl:sequence select= 
     "my:buildXml2($vsubSegments)"/> 
    </xsl:element> 
    </xsl:for-each-group> 
</xsl:function> 
</xsl:stylesheet> 

當在下面的XML文檔(使用稍微更復雜的字符串,使這個甚至更具挑戰性)施加:

<t> 
author 
    ~time 
    ~assignedAuthor 
    ~assignedAuthor/id 
    ~assignedAuthor/addr 
    ~assignedAuthor/telecom 
    ~assignedAuthor/assignedPerson/name 
    ~assignedAuthor/assignedPerson/address~ 
</t> 

產生想要的,正確的結果

<author> 
    <time/> 
    <assignedAuthor> 
     <id/> 
     <addr/> 
     <telecom/> 
     <assignedPerson> 
     <name/> 
     <address/> 
     </assignedPerson> 
    </assignedAuthor> 
</author> 

說明

「段」 的序列的
  1. 符號化。使用tokenize()

  2. 分組(xsl:for-each-group)與屬性group-adjacent使用作爲分組鍵第一個「子分段」。

  3. 對於每個組遞歸構建XML子樹。使用current-grouping-key()current-group()

+0

不錯。 :-)我希望我也有時間去研究它。 – LarsH 2011-12-25 04:48:28

+0

@LarsH:是的,這是一個很好的問題,也是一個非常有趣的分組用例。 – 2011-12-25 04:56:02