1

我在下面的模式中有字符串

作者~时间~assignedAuthor~assignedAuthor/id~assignedAuthor/addr~assignedAuthor/telecom~assignedAuthor/assignedPerson/name~

第一个元素一直是根元素(在上面的字符串模式中它是author),其余的都是用字符“~”删除的子元素。我想通过使用上面的字符串模式使用 XSLT 2.0 创建 XML,并且我想在下面生成 XML。

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

我可以为此提供可能的解决方案吗?

4

1 回答 1

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

于 2011-12-24T06:58:43.463 回答