使用 XSLT 格式化 XML

使用 XSLT 格式化 XML

在平常工作中经常遇到要求对 XML 进行格式化的情况, XSLT相比较于写纯java代码操作 org.w3c.dom.Document 更加方便,利于维护。
下面会用一个java例子来介绍XSLT的基本用法。

场景

原始的XML

<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<school>
    <students>
        <student>
            <name>Lucy</name>
            <gender>Female</gender>
        </student>
        <student>
            <name>Lily</name>
            <gender>Female</gender>
        </student>
        <student>
            <name>Tom</name>
            <gender>Male</gender>
        </student>
    </students>
</school>

想要把所有的女性选出来 放入下面的xml结构中

<?xml version="1.0" encoding="UTF-8"?>
<cityMall>
    <store>
        <name>Lucy</name>
        <name>Lily</name>
    </store>
</cityMall>

怎么用XSLT 实现这种转化呢。
如下 XSLT - formater.xml

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" omit-xml-declaration="yes"
        encoding="UTF-8" indent="yes" />
    <!-- GLOBAL VARIABLES -->
    <xsl:variable name="target" select="/school/students" />

    <!-- transform template -->
    <xsl:template match="/">
        <cityMall>
            <store>
                <xsl:for-each select="$target/student">
                    <xsl:if test="(boolean(gender ='Female'))">
                        <xsl:copy-of select="name"></xsl:copy-of>
                    </xsl:if>
                </xsl:for-each>
            </store>
        </cityMall>
    </xsl:template>
</xsl:stylesheet>

遍历所有的 student element, 发现geneder为Female时,选择它。

怎么使用JAVA 调用它呢。

Formater.java

import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import com.ericsson.dve.jdv.m2m.core.util.M2MTransformerFactory;

public class Formater {
    private static final Logger LOGGER = LoggerFactory.getLogger(M2MTransformerFactory.class);

    public static void main(String[] args) {
        Formater formater = new Formater();

        try {
            Document document = formater.getSrcDocument("test/META-INF/source.xml");

            Document transformedResponse = formater.transformDoc(document);

            System.out.println(formater.xml2Str(transformedResponse));

        } catch (Exception e) {
            LOGGER.error("Exception", e);
        }

    }

    private Document getSrcDocument(String srcFilePath) throws SAXException, IOException, ParserConfigurationException {
        Document document = null;
        File srcDocFile = new File("test/META-INF/source.xml");
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder;
        builder = factory.newDocumentBuilder();
        document = builder.parse(srcDocFile);
        return document;
    }

    private Document transformDoc(Document srcDoc) throws TransformerConfigurationException, TransformerException {
        DOMResult tResult = new DOMResult();

        M2MTransformerFactory.getTransformer("/META-INF/xslt/NewFile2.xml").transform(new DOMSource(srcDoc), tResult);

        Document transformedResponse = (Document) tResult.getNode();
        return transformedResponse;
    }

    private String xml2Str(Document document) throws TransformerException {
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transformer = factory.newTransformer();

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        transformer.transform(new DOMSource(document), new StreamResult(byteArrayOutputStream));

        return byteArrayOutputStream.toString();
    }
}

TransformerFactory.java

import java.io.InputStream;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.stream.StreamSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TransformerFactory {
    private static final Logger LOGGER = LoggerFactory.getLogger(TransformerFactory.class);

    private static javax.xml.transform.TransformerFactory factory;
    private static Transformer transformer = null;

    static {
        factory = javax.xml.transform.TransformerFactory.newInstance();
        factory.setURIResolver(new XsltURIResolver());
    }

    private TransformerFactory() {

    }

    /**
     * Creates Transformer from the file passed as argument.
     *
     */
    public static Transformer getTransformer(String xsltFileName) throws TransformerConfigurationException {

        if (xsltFileName == null || xsltFileName.isEmpty()) {
            throw new IllegalArgumentException("xslFileName argument must not be null");
        }

        try {
            if (transformer == null) {
                return factory.newTransformer(
                        new StreamSource(TransformerFactory.class.getResourceAsStream(xsltFileName)));
            }

            return transformer;
        } catch (TransformerConfigurationException e) {
            LOGGER.error("Error creating xsl Transformer for file: {}", xsltFileName);
            throw e;
        }

    }

    /**
     * Transformer factory URI resolver
     *
     */
    static class XsltURIResolver implements URIResolver {

        public Source resolve(String href, String base) throws TransformerException {

            InputStream is = TransformerFactory.class.getResourceAsStream("/META-INF/xslt/" + href);
            if (is == null) {
                throw new TransformerException("Transformation file " + href + " not found");
            }
            return new StreamSource(is);
        }
    }
}

Note: formater.xml 应该放在Transformer.java 的相对路径 /META-INF/xslt/ 下面

之后如果需要不同格式的document,都可以直接修改formater.xml 来完成。 不仅直观,后续维护也更加方便。

XSLT 其他用法

  • chose, when ,otherwise. 进行逻辑判断。
<xsl:choose>
    <xsl:when test="ResultData">
        <xsl:copy-of select="ResultData/*"></xsl:copy-of>
    </xsl:when>
    <xsl:otherwise>
        <xsl:copy-of select="*"></xsl:copy-of>
    </xsl:otherwise>
</xsl:choose>
  • xls:if xsl:element 动态的生成xml的element.
<xsl:if test="not(boolean(/school/student/name =''))">
    <xsl:element name="new_name">
        <xsl:value-of select="/school/student/name"></xsl:value-of>
    </xsl:element>
</xsl:if>

优点:XSLT 还有很多其他用法方便xml的处理。特别适合于业务逻辑复杂的转换,
劣势:t比单纯的java 处理 org.w3c.dom.Document 处理速度慢。 但我并没有进行大量实验就行分析对比。只是在使用过程中发现 performance略有不足。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java XSLT模板化XML是指使用Java编程语言的XSLT技术来将XML数据与XSLT模板文件进行结合,生成新的XML文档。在Java中,你可以使用Java内置的javax.xml.transform包中的Transformer类来完成这个过程。首先,你需要创建一个Transformer对象,并指定XSLT模板文件的位置。然后,你可以使用Transformer对象的transform()方法来将XML数据与XSLT模板进行处理,生成新的XML文档。在这个过程中,XSLT模板文件中定义了XML数据的转换规则,包括选择和过滤节点、应用样式和格式等。通过使用XSLT模板化XML,你可以方便地对XML数据进行转换和处理,以满足不同的需求。,从Java Web开发的角度来看,使用XSLT模板化XML可以实现动态生成HTML或其他前端页面。XML数据可以作为数据源,XSLT模板文件可以定义页面的样式和布局。通过XSLT模板化XML,你可以将XML数据转换为具有特定样式和布局的HTML或其他前端页面,从而实现动态的数据展示和交互。这种方式在Java Web开发中被广泛应用,以提供灵活和可定制的界面效果。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [XML实验报告(XML,DTD,SCHEMA,XPATH,XSLT,利用JAVA对XML进行读写操作)](https://blog.csdn.net/qq_51513626/article/details/122017954)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [JAVA WEB 开发详解:XML+XSLT+SERVLET+JSP 深入剖析与实例应用.part2](https://download.csdn.net/download/ljtt123/4479797)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值