1. 程式人生 > 其它 >net根據list建立xml_從零開始寫文字編輯器(二十五):支援對目錄URL遍歷XML資源...

net根據list建立xml_從零開始寫文字編輯器(二十五):支援對目錄URL遍歷XML資源...

技術標籤:net根據list建立xml

前言

現階段的資源載入是固定的 string.xml 來載入所有字串資源。但一個檔案顯然不利於編輯和分類。當我把所有選單項字串列出時,已經多達230個,更不論對話方塊/按鈕等使用的字串,因此必須支援靈活遍歷 XML。本篇以/editor/res/string/下的所有字串的xml為例,說明該流程。

類資源訪問

類動態載入是java提供的原生API,與JVM的類載入機制有關。這裡不詳細說明。

public void test() throws URISyntaxException {
    URL url = Test.class.getResource("/editor/res/string");
    File file = new File(url.toURI());
    System.out.println(file.isDirectory());
    for (String string : file.list()) {
        System.out.println(string);
    }
}

上述測試程式碼,基本完成了遍歷,主要是URL/URI/File三者之間的轉換。

6bcb1959df8df028f85f737b2420aed8.png

輸出

true
string.xml
string_menu_edit.xml
string_menu_file.xml
string_menu_source.xml
Test.class

遍歷資源目錄

package editor.resource.xml.declaration;

import java.io.File;
import java.io.FilenameFilter;
import java.net.URISyntaxException;
import java.net.URL;

public class Directory {

    public static final String STRING = "/editor/res/string";
    public static final String ACCELERATOR = "/editor/res/accelerator";
    public static final String MENU = "/editor/res/menu";

    public File[] listXmlFile(String directory) throws URISyntaxException {
        URL url = Directory.class.getResource(directory);
        File file = new File(url.toURI());
        if (file.isDirectory()) {
            return file.listFiles(filenameFilter);
        } else {
            return null;
        }
    }

    private FilenameFilter filenameFilter = new FilenameFilter() {

        @Override
        public boolean accept(File dir, String name) {
            return name.endsWith(".xml");
        }

    };
}

遍歷每一個 File 後,在原先的RMake的列印邏輯做細節調整

public void make() throws URISyntaxException {
    Directory directory = new Directory();
    File[] files = directory.listXmlFile(Directory.STRING);
    System.out.println("public static final class string {");
    for (File file : files) {
        stringXMLReader.read(file);
    }
    System.out.println("}");
}

輸出

public static final class string {
    public static final int bold = 3029637;
    public static final int turn_off_grammar_constraints = -1600293620;
    public static final int reload_dependencies = -524089841;
    public static final int expand_all = 540060284;
    public static final int collapse_all = 1874603535;
    public static final int undo = 3594468;
    public static final int redo = 3496446;
    public static final int cut = 98882;
    public static final int copy = 3059573;
    public static final int paste = 106438291;
    public static final int delete = -1335458389;
    public static final int select_all = -1655636002;
    public static final int toggle_block_selection = 1659473263;
    public static final int find_replace = -760510930;
    ...
}

檢查重複定義

當一個資源在多個XML中重複定義了,可以遍歷產生一個該資源的定義樹。

  • 步驟
  1. 遍歷檔案
  2. 遍歷資源
  3. 獲得資源名稱
    1. 建立該名字的定義樹
    2. 新增定義檔案記錄
  4. 遍歷結束
    1. 列印所有資源的定義樹
    2. 對重複定義輸出錯誤日誌
  • 建立定義樹的節點
package editor.resource.xml.declaration.tree;

import java.io.File;
import java.util.HashMap;

import javax.swing.tree.DefaultMutableTreeNode;

public class FileNodeHelper {

    public FileNodeHelper(DefaultMutableTreeNode rootNode) {
        this.rootNode = rootNode;
    }

    private DefaultMutableTreeNode rootNode;

    private HashMap<Integer, DefaultMutableTreeNode> cache = new HashMap<Integer, DefaultMutableTreeNode>();

    public boolean hasNode(File file) {
        return getNode(file) != null;
    }

    public DefaultMutableTreeNode getNode(File file) {
        return cache.get(file.getName().hashCode());
    }

    public DefaultMutableTreeNode addNode(File file) {
        DefaultMutableTreeNode defaultMutableTreeNode = new DefaultMutableTreeNode(file);
        cache.put(file.getName().hashCode(), defaultMutableTreeNode);
        rootNode.add(defaultMutableTreeNode);
        return defaultMutableTreeNode;
    }
}
  • 列印重複定義項
private void listRepeat() {
    for (NameDeclaration nameDeclaration : cache.values()) {
        DefaultMutableTreeNode rootNode = nameDeclaration.getRootNode();
        if (rootNode.getChildCount() > 1) {
            System.err.printf(""%s" 被重複定義:n", nameDeclaration.getName());
            for (int i = 0; i < rootNode.getChildCount(); i++) {
                DefaultMutableTreeNode fileNode = (DefaultMutableTreeNode) rootNode.getChildAt(i);
                File file = (File) fileNode.getUserObject();
                System.out.println(file.getName());
            }
            System.out.println();
        }
    }

}
  • 輸出
"rename" 被重複定義:
string_menu_file.xml
string_menu_refactor.xml

"move" 被重複定義:
string_menu_file.xml
string_menu_refactor.xml

aa5d0877fda987162d5803726ff1f049.png

PS:目前只定位到檔案,並沒有精確到行,因為XML解析時,把行號資訊丟棄了。

修改資源名

一般新增合適的字尾來解決同名問題

比如:

把檔案選單的資源字串 rename 改為 rename_file,另一個則不必改動。

Magic Text 依然存在

可惜:magic text並沒有被徹底消滅,從 "string.xml" 變為了 "/editor/res/string",在後續開發中,相信會形成框架,逐步清理掉它們。

以上~