如何根据某些规则重构XML文件?

时间:2012-09-01 10:19:02

标签: java xml xslt jsf-2 facelets

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

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

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

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

3 个答案:

答案 0 :(得分:1)

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

不要浪费太多时间编写最先进的JSF迁移器来实现这一目标,尝试做一些能够以最小的努力进行几乎所有更改然后通过一切都行得通。如果您想使用Facelets中的功能作为模板和复合组件,那么您最终还是会手动重构代码。

答案 1 :(得分:0)

我的赌注是DOM。处理文档并将其另存为新文件(或覆盖)。这只是你可以递归申请所有文件的几条规则。

答案 2 :(得分:0)

这对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. <view>已被删除。

  2. <head><body>转换为<h:head><h:body>

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