首页 > 解决方案 > 如何在 wffweb 中正确呈现 HTML 树中的任意文本内容

问题描述

以下 wffweb java 代码(相对接近wffweb网站上提供的示例):

        html = new Html(null) {{
            new Head(this) {{
                new TitleTag(this) {{
                    new NoTag(this, "No <tags> inside, please!");
                }};
            }};
        }};

        System.out.println(html.toHtmlString());

打印出来:

<html><head><title>No <tags> inside, please!</title></head></html>

我期望(并且需要)是使用相应的机制(在这种情况下<tags>应该是)转义文本节点内的任何 XML 字符。&lt;tags&gt;

在输出中转义文本节点内的 XML 语法的正确(或推荐)方法是什么?我显然可以在添加字符串之前自己包装 XML 语法,但这听起来不对,我不应该每次都转义/取消转义文本节点值,我希望它们作为常规字符串存储在树中,并且仅在序列化期间修改。

标签: javawffweb

解决方案


可以借助commons-textorg.apache.commons.text.StringEscapeUtils.escapeHtml4中的方法来实现。

这是我的XmlUtil课:

import org.apache.commons.text.StringEscapeUtils;

public class XmlUtil {    

    //using StringEscapeUtils.escapeHtml4
    public static String convertSymbolsToEntityChars(String text) {
        return StringEscapeUtils.escapeHtml4(text);
    }

    public static void main(String[] args) {
        System.out.println(convertSymbolsToEntityChars("No <tags> inside, please!"));
    }
}

如果您运行该main方法,它将打印No &lt;tags&gt; inside, please! 如果您更喜欢jsoup方式,ENTITIES_STRING如果您希望支持更多实体字符,则必须更新。

所以你的最终代码将如下所示:

html = new Html(null) {{                                 
    new Head(this) {{                                    
        new TitleTag(this) {{                            
            new NoTag(this, XmlUtil.convertSymbolsToEntityChars("No <tags> inside, please!", true));
        }};                                              
    }};                                                  
}};                                                      

System.out.println(html.toHtmlString());   

现在将打印:

<html><head><title>No &lt;tags&gt; inside, please!</title></head></html>

请注意,它NoTag支持纯文本和 HTML。

new NoTag(this, "No <tags> inside, please!");等于

//constructor params = (parent, content, contentTypeHtml)
new NoTag(this, "No <tags> inside, please!", false);

因此,如果您传递的内容应该被视为 HTML,那么new NoTag(this, "No &lt;tags&gt; inside, please!", true);这是推荐的方式。


从最新版本的wffweb 开始,建议使用功能样式编码而不是匿名样式编码。例如:

Html rootTag = new Html(null).give(html -> {
    new Head(html).give(head -> {
        new TitleTag(head).give(title -> {
            new NoTag(title, "No &lt;tags&gt; inside, please!", true);            
        });
    });    
});
System.out.println(rootTag.toHtmlString());

如果您只想显示No &lt;tags&gt; inside, please!bytoHtmlString但又想从中获取原始未转换的字符串,TitleTag则可以使用SharedTagContent<String>而不是NoTag. 观看有关其用法的视频

例如:

SharedTagContent<String> titleSTC = new SharedTagContent<>("No <tags> inside, please!", true);                        

Html rootTag = new Html(null).give(html -> {                                                                          
    new Head(html).give(head -> {                                                                                     
        new TitleTag(head).give(title -> {                                                                            
            title.subscribeTo(titleSTC, content -> {                                                                  
                String innerText = content.getContent();                                                              
                if (innerText != null && content.isContentTypeHtml()) {                                               
                    String contentHavingEntityCharacters = XmlUtil.convertSymbolsToEntityChars(innerText);            
                    return new SharedTagContent.Content<>(contentHavingEntityCharacters, content.isContentTypeHtml());
                }                                                                                                     
                return content;                                                                                       
            });                                                                                                       
        });                                                                                                           
    });                                                                                                               
});                                                                                                                   
System.out.println("rootTag.toHtmlString() = " + rootTag.toHtmlString());                                             
System.out.println("titleSTC.getContent() = " + titleSTC.getContent());                                               

//to get unconverted text from TitleTag                                                                               
TitleTag titleTag = TagRepository.findOneTagAssignableToTag(TitleTag.class, rootTag);                                 
String titleTagInnerContent = (String) titleTag.getSharedTagContent().getContent();                                   
System.out.println("titleTagInnerContent = " + titleTagInnerContent);

它打印

rootTag.toHtmlString() = <html><head><title>No &lt;tags&gt; inside, please!</title></head></html>
titleSTC.getContent() = No <tags> inside, please!
titleTagInnerContent = No <tags> inside, please!

推荐阅读