【问题标题】:How to restructure an XML file based on some rules?如何根据一些规则重构 XML 文件?
【发布时间】:2012-08-26 22:54:04
【问题描述】:

我有数千个基于 JSF1.2 的 JSP 文件,但我想迁移到 JSF2.0 并改用 facelets,所以我必须根据 some defined rules 更改它们的结构,例如一些必需的更改如下:

  • 我应该删除<view>标签
  • 我应该将<head> 转换为<h:head>
  • 我应该将<body> 转换为<h:body>
  • 我应该更改一些命名空间声明

由于文件数量巨大,我决定开发一个迷你应用程序来自动化这个过程,否则我必须手动修改很多文件!

我想知道这样做的最佳解决方案是什么?我应该使用 XSLT 还是应该将 JSP 文件解析为 XML 文件并通过 DOM 修改它们的结构?

【问题讨论】:

    标签: java xml xslt jsf-2 facelets


    【解决方案1】:

    这些不是简单的文本替换(您需要向文件添加新的名称空间,即 Facelets 中的 composition 名称空间,文件扩展名从 .JSP 更改为 .XHTML 等),更简单的选择似乎是 XSLT,因为您可以在其中使用某种逻辑,但是,真正使用 Facelets 所需的更改对于任何自动化流程来说都不是一件容易的事。

    不要浪费太多时间编写最先进的 JSF 迁移器来实现这一点,尝试做一些可以用最少的努力进行几乎所有更改的事情,然后通过以下方式进行修改手使一切正常。如果您想将 Facelets 中的功能用作模板和复合组件,那么您最终还是要手动重构代码。

    【讨论】:

      【解决方案2】:

      我的赌注是 DOM。操作文档并将其另存为新文件(或覆盖)。这只是您可以递归地应用于所有文档的几个规则。

      【讨论】:

        【解决方案3】:

        这对于 XSLT 来说是直截了当的。

        这是一个执行所有必需替换的示例

        鉴于此 XML 源文件

        <html xmlns:old="old:namespace">
         <head>
          <meta property="og:type" content="webcontent"/>
         </head>
         <view>Some View</view>
         <body>
           The Body here.
         </body>
        </html>
        

        此转换执行所有请求的更改:

        <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
         xmlns:h="some:h" xmlns:old="old:namespace" xmlns:new="new:new"
         exclude-result-prefixes="h new old">
         <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
         <xsl:strip-space elements="*"/>
        
         <xsl:variable name="vnsH" select="document('')/*/namespace::h"/>
         <xsl:variable name="vnsNew" select="document('')/*/namespace::new"/>
        
         <xsl:template match="*">
          <xsl:element name="{name()}" namespace="{namespace-uri()}">
           <xsl:copy-of select="namespace::*[not(name()='old')]"/>
           <xsl:if test="namespace::old">
             <xsl:copy-of select="$vnsNew"/>
           </xsl:if>
           <xsl:apply-templates select="@*|node()"/>
          </xsl:element>
         </xsl:template>
        
         <xsl:template match="@*">
          <xsl:attribute name="{name()}" namespace="{namespace-uri()}">
            <xsl:value-of select="."/>
          </xsl:attribute>
         </xsl:template>
        
         <xsl:template match="node()[not(self::*)]">
             <xsl:copy/>
         </xsl:template>
        
         <xsl:template match="view"/>
        
         <xsl:template match="/*">
          <xsl:element name="{name()}">
           <xsl:copy-of select="namespace::*[not(name()='old')]|$vnsH"/>
           <xsl:if test="namespace::old">
             <xsl:copy-of select="$vnsNew"/>
           </xsl:if>
           <xsl:apply-templates select="@*|node()"/>
          </xsl:element>
         </xsl:template>
        
         <xsl:template match="head|body">
          <xsl:element name="h:{name()}" namespace="some:h">
            <xsl:copy-of select="namespace::*[not(name()='old')]"/>
            <xsl:if test="namespace::old">
             <xsl:copy-of select="$vnsNew"/>
            </xsl:if>
            <xsl:apply-templates select="node()|@*"/>
          </xsl:element>
         </xsl:template>
        </xsl:stylesheet>
        

        当应用于上述 XML 文档时,会产生想要的正确结果:

        <html xmlns:h="some:h" xmlns:new="new:new">
           <h:head>
              <meta property="og:type" content="webcontent"/>
           </h:head>
           <h:body>
           The Body here.
         </h:body>
        </html>
        

        请注意

        1. &lt;view&gt; 已被删除。

        2. &lt;head&gt;&lt;body&gt; 转换为 &lt;h:head&gt;&lt;h:body&gt;

        3. old 命名空间现在替换为 new 命名空间。

        【讨论】:

          猜你喜欢
          • 2012-03-23
          • 1970-01-01
          • 2016-06-25
          • 1970-01-01
          • 1970-01-01
          • 2016-04-10
          • 2018-11-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多