【问题标题】:XSLT: Transform nested XML into Ruby CodeXSLT:将嵌套的 XML 转换为 Ruby 代码
【发布时间】:2012-12-22 14:14:13
【问题描述】:

我有几个需要生成 Ruby 代码的 XML 文件。我的XML结构如下:

<acronym_list> 
   xmlns="http://www.example.com/xsds" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
   xsi:schemaLocation="http://www.example.com/xsds           
                       http://www.example.com/xsds/acronyms.xsd">
 <item>
   <metadata>
     <release>...</release>
     <id>...</id>
     <checkdigit>...<checkdigit>
     <status>...</status>
     <date_added>...</date_added>
     <date_modified>...</date_modified>
     <language>...</language>
     <license_url>...</license_url>
   </metadata>
   <info>
     <name>...</name>
   </info>
 </item>
</acronym_list>

在这种情况下,我们讨论的是首字母缩略词。 item 元素(及其子元素)对于我列表中的每个首字母缩写词都会重复。我还有几个结构相似的文件,info 元素有更多的子元素。

我试图输出的 Ruby 代码如下所示:

Module acronym_list
    def self.included(other)
        include SAXMachine
        SAXMachine.configure(other) do |c|
          c.element :metadata, :class => metadata
          c.element :info, :class => info
        end
    end

    class metadata
       include SAXMachine
       c.element :release
       c.element :id
       c.element :checkdigit
       c.element :status
       c.element :date_added
       c.element :date_modified
       c.element :language
       c.element :license_url
    end

    class info
       include SAXMachine
       c.element :name
    end           
end

我尝试解析的其他 XML 文件遵循相同的模式。我已经设法让第一部分使用模块声明,但我不知道足够的 XSLT 来获得其余部分。

有人能帮我解决这个问题吗?

【问题讨论】:

    标签: ruby xml xslt code-generation


    【解决方案1】:

    我不知道 ruby​​ 语法,所以我不确定缩进或空格是否重要,但与样式表有关

    <xsl:stylesheet version="1.0" 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:acs="http://www.example.com/xsds"
      exclude-result-prefixes="acs">
    
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:template match="acs:acronym_list">
    Module <xsl:value-of select="local-name()"/>
      def self.included(other)
         include SAXMachine
         SAXMachine.configure(other) do |c|
           <xsl:apply-templates select="acs:item/acs:*" mode="config"/>
         end
      end
    
      <xsl:apply-templates select="acs:item/acs:*" mode="class"/>
    end
    </xsl:template>
    
    <xsl:template match="acs:item/acs:*" mode="config">
            c.element :<xsl:value-of select="local-name()"/>, :class => <xsl:value-of select="local-name()"/>
    </xsl:template>  
    
    <xsl:template match="acs:item/acs:*" mode="class">
      class <xsl:value-of select="local-name()"/>
        include SAXMachine
        <xsl:apply-templates mode="class"/>
      end
    </xsl:template>
    
    <xsl:template match="acs:item/acs:*/acs:*" mode="class">
        c.element :<xsl:value-of select="local-name()"/>
    </xsl:template>
    
    </xsl:stylesheet>
    

    Saxon 6.5.5 转换输入

    <acronym_list
       xmlns="http://www.example.com/xsds" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
       xsi:schemaLocation="http://www.example.com/xsds           
                           http://www.example.com/xsds/acronyms.xsd">
     <item>
       <metadata>
         <release>...</release>
         <id>...</id>
         <checkdigit>...</checkdigit>
         <status>...</status>
         <date_added>...</date_added>
         <date_modified>...</date_modified>
         <language>...</language>
         <license_url>...</license_url>
       </metadata>
       <info>
         <name>...</name>
       </info>
     </item>
    </acronym_list>
    

    进入输出

    Module acronym_list
      def self.included(other)
         include SAXMachine
         SAXMachine.configure(other) do |c|
    
            c.element :metadata, :class => metadata
            c.element :info, :class => info
         end
      end
    
    
      class metadata
        include SAXMachine
    
        c.element :release
        c.element :id
        c.element :checkdigit
        c.element :status
        c.element :date_added
        c.element :date_modified
        c.element :language
        c.element :license_url
      end
    
      class info
        include SAXMachine
    
        c.element :name
      end
    
    end
    

    【讨论】:

    • 这太棒了。谢谢!如果我想对 item 元素进行通用处理(即,我有一个带有 acronym_item 的文件,另一个带有 assets_item 的文件),我可以像您在上面所做的那样对模式采取类似的方法吗?
    • 在您发布的示例中,有一个acronym_list 元素,但没有acronym_item,所以我不确定asset_item 会出现在哪里。而且还不清楚你想要哪个输出。如果所需的输出结构没有任何变化,那么只需为模板提供匹配模式的枚举就足够了,例如&lt;xsl:template match="acs:acronym_list | acs:asset_list"&gt;...&lt;/xsl:template&gt;。模式有助于多次处理节点,即第一次使用第一种模式以某种方式以某种方式输出,第二次以第二种方式输出
    猜你喜欢
    • 2012-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-24
    相关资源
    最近更新 更多