JSON数据清洗工具

我将设计一个直观的JSON数据清洗工具,允许用户输入原始JSON数据,应用各种清洗操作,并查看清洗后的结果。

设计思路

· 提供原始JSON输入区域
· 实现常用数据清洗功能(过滤、映射、去重、格式化等)
· 实时显示清洗后的JSON结果
· 添加数据验证和错误提示
· 设计直观的用户界面

实现代码

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JSON数据清洗工具</title>
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }
        
        body {
            background-color: #f5f7f9;
            color: #333;
            line-height: 1.6;
            padding: 20px;
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
            background-color: #fff;
            border-radius: 10px;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
            overflow: hidden;
        }
        
        header {
            background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
            color: white;
            text-align: center;
            padding: 20px;
        }
        
        h1 {
            font-size: 2.2rem;
            margin-bottom: 10px;
        }
        
        .description {
            font-size: 1.1rem;
            opacity: 0.9;
            max-width: 800px;
            margin: 0 auto;
        }
        
        .main-content {
            display: flex;
            flex-wrap: wrap;
            padding: 20px;
            gap: 20px;
        }
        
        .input-section, .output-section {
            flex: 1;
            min-width: 300px;
        }
        
        .section-title {
            font-size: 1.3rem;
            margin-bottom: 15px;
            color: #2c3e50;
            display: flex;
            align-items: center;
        }
        
        .section-title i {
            margin-right: 10px;
            color: #3498db;
        }
        
        textarea {
            width: 100%;
            height: 250px;
            padding: 15px;
            border: 1px solid #ddd;
            border-radius: 5px;
            font-family: 'Courier New', Courier, monospace;
            font-size: 14px;
            resize: vertical;
            box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
            transition: border-color 0.3s;
        }
        
        textarea:focus {
            outline: none;
            border-color: #3498db;
            box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(52, 152, 219, 0.4);
        }
        
        .controls {
            background-color: #f8f9fa;
            padding: 20px;
            border-top: 1px solid #eee;
        }
        
        .control-group {
            margin-bottom: 20px;
        }
        
        .control-title {
            font-weight: 600;
            margin-bottom: 10px;
            color: #2c3e50;
        }
        
        .buttons {
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
            margin-bottom: 15px;
        }
        
        button {
            padding: 10px 15px;
            background-color: #3498db;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            font-weight: 500;
            transition: background-color 0.3s, transform 0.2s;
            display: flex;
            align-items: center;
        }
        
        button i {
            margin-right: 5px;
        }
        
        button:hover {
            background-color: #2980b9;
            transform: translateY(-2px);
        }
        
        button:active {
            transform: translateY(0);
        }
        
        .primary-btn {
            background-color: #2ecc71;
        }
        
        .primary-btn:hover {
            background-color: #27ae60;
        }
        
        .danger-btn {
            background-color: #e74c3c;
        }
        
        .danger-btn:hover {
            background-color: #c0392b;
        }
        
        .status {
            margin-top: 15px;
            padding: 10px;
            border-radius: 5px;
            font-size: 14px;
        }
        
        .error {
            background-color: #ffebee;
            color: #c62828;
            border: 1px solid #ef9a9a;
        }
        
        .success {
            background-color: #e8f5e9;
            color: #2e7d32;
            border: 1px solid #a5d6a7;
        }
        
        .info {
            background-color: #e3f2fd;
            color: #1565c0;
            border: 1px solid #90caf9;
        }
        
        .output-info {
            display: flex;
            justify-content: space-between;
            margin-bottom: 10px;
        }
        
        .copy-btn {
            padding: 5px 10px;
            font-size: 12px;
            background-color: #7f8c8d;
        }
        
        .copy-btn:hover {
            background-color: #636e72;
        }
        
        @media (max-width: 768px) {
            .main-content {
                flex-direction: column;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>JSON数据清洗工具</h1>
            <p class="description">输入原始JSON数据,应用清洗操作,获取格式化且清洗后的JSON输出</p>
        </header>
        
        <div class="main-content">
            <div class="input-section">
                <h2 class="section-title">
                    <i>📥</i> 原始JSON输入
                </h2>
                <textarea id="inputJson" placeholder='请输入JSON数据,例如:{"name": "John", "age": 30, "city": "New York"}'></textarea>
                
                <div class="controls">
                    <div class="control-group">
                        <div class="control-title">数据清洗选项</div>
                        <div class="buttons">
                            <button onclick="formatJson()">
                                <i>🔄</i> 格式化JSON
                            </button>
                            <button onclick="removeNulls()">
                                <i></i> 移除空值
                            </button>
                            <button onclick="minifyJson()">
                                <i>📏</i> 压缩JSON
                            </button>
                        </div>
                    </div>
                    
                    <div class="control-group">
                        <div class="control-title">数据操作</div>
                        <div class="buttons">
                            <button class="primary-btn" onclick="processJson()">
                                <i></i> 应用清洗
                            </button>
                            <button class="danger-btn" onclick="clearAll()">
                                <i>🗑️</i> 清除所有
                            </button>
                        </div>
                    </div>
                    
                    <div id="status" class="status info">
                        就绪:请输入JSON数据并选择清洗选项
                    </div>
                </div>
            </div>
            
            <div class="output-section">
                <h2 class="section-title">
                    <i>📤</i> 清洗后的JSON
                </h2>
                <div class="output-info">
                    <span>输出结果</span>
                    <button class="copy-btn" onclick="copyOutput()">
                        <i>📋</i> 复制到剪贴板
                    </button>
                </div>
                <textarea id="outputJson" readonly placeholder="清洗后的JSON将显示在这里"></textarea>
            </div>
        </div>
    </div>

    <script>
        function showStatus(message, type) {
            const statusEl = document.getElementById('status');
            statusEl.textContent = message;
            statusEl.className = 'status ' + type;
        }
        
        function isValidJson(jsonString) {
            try {
                JSON.parse(jsonString);
                return true;
            } catch (e) {
                return false;
            }
        }
        
        function processJson() {
            const inputJson = document.getElementById('inputJson').value.trim();
            
            if (!inputJson) {
                showStatus('错误:请输入JSON数据', 'error');
                return;
            }
            
            if (!isValidJson(inputJson)) {
                showStatus('错误:输入的JSON格式无效', 'error');
                return;
            }
            
            try {
                const parsedJson = JSON.parse(inputJson);
                // 这里可以添加更复杂的清洗逻辑
                const cleanedJson = JSON.stringify(parsedJson, null, 2);
                
                document.getElementById('outputJson').value = cleanedJson;
                showStatus('成功:JSON数据已清洗并格式化', 'success');
            } catch (error) {
                showStatus('错误:处理JSON时发生错误 - ' + error.message, 'error');
            }
        }
        
        function formatJson() {
            const inputJson = document.getElementById('inputJson').value.trim();
            
            if (!inputJson) {
                showStatus('错误:请输入JSON数据', 'error');
                return;
            }
            
            if (!isValidJson(inputJson)) {
                showStatus('错误:输入的JSON格式无效', 'error');
                return;
            }
            
            try {
                const parsedJson = JSON.parse(inputJson);
                const formattedJson = JSON.stringify(parsedJson, null, 2);
                
                document.getElementById('inputJson').value = formattedJson;
                document.getElementById('outputJson').value = formattedJson;
                showStatus('成功:JSON已格式化', 'success');
            } catch (error) {
                showStatus('错误:格式化JSON时发生错误 - ' + error.message, 'error');
            }
        }
        
        function removeNulls() {
            const inputJson = document.getElementById('inputJson').value.trim();
            
            if (!inputJson) {
                showStatus('错误:请输入JSON数据', 'error');
                return;
            }
            
            if (!isValidJson(inputJson)) {
                showStatus('错误:输入的JSON格式无效', 'error');
                return;
            }
            
            try {
                const parsedJson = JSON.parse(inputJson);
                
                // 递归移除null和空字符串值
                function removeEmptyValues(obj) {
                    if (Array.isArray(obj)) {
                        return obj
                            .filter(item => item !== null && item !== '')
                            .map(item => typeof item === 'object' ? removeEmptyValues(item) : item);
                    } else if (typeof obj === 'object' && obj !== null) {
                        const cleanedObj = {};
                        for (const [key, value] of Object.entries(obj)) {
                            if (value !== null && value !== '') {
                                cleanedObj[key] = typeof value === 'object' ? removeEmptyValues(value) : value;
                            }
                        }
                        return cleanedObj;
                    }
                    return obj;
                }
                
                const cleanedJson = removeEmptyValues(parsedJson);
                const formattedJson = JSON.stringify(cleanedJson, null, 2);
                
                document.getElementById('outputJson').value = formattedJson;
                showStatus('成功:已移除空值和空字符串', 'success');
            } catch (error) {
                showStatus('错误:移除空值时发生错误 - ' + error.message, 'error');
            }
        }
        
        function minifyJson() {
            const inputJson = document.getElementById('inputJson').value.trim();
            
            if (!inputJson) {
                showStatus('错误:请输入JSON数据', 'error');
                return;
            }
            
            if (!isValidJson(inputJson)) {
                showStatus('错误:输入的JSON格式无效', 'error');
                return;
            }
            
            try {
                const parsedJson = JSON.parse(inputJson);
                const minifiedJson = JSON.stringify(parsedJson);
                
                document.getElementById('outputJson').value = minifiedJson;
                showStatus('成功:JSON已压缩', 'success');
            } catch (error) {
                showStatus('错误:压缩JSON时发生错误 - ' + error.message, 'error');
            }
        }
        
        function clearAll() {
            document.getElementById('inputJson').value = '';
            document.getElementById('outputJson').value = '';
            showStatus('已清除所有内容', 'info');
        }
        
        function copyOutput() {
            const outputTextarea = document.getElementById('outputJson');
            if (outputTextarea.value) {
                outputTextarea.select();
                document.execCommand('copy');
                showStatus('成功:输出已复制到剪贴板', 'success');
                
                // 取消选中文本
                window.getSelection().removeAllRanges();
            } else {
                showStatus('错误:没有内容可复制', 'error');
            }
        }
        
        // 添加示例JSON到输入框
        document.getElementById('inputJson').value = JSON.stringify({
            "name": "John Doe",
            "age": 30,
            "email": "john.doe@example.com",
            "address": {
                "street": "123 Main St",
                "city": "Anytown",
                "zipcode": "12345"
            },
            "hobbies": ["reading", "traveling", "photography"],
            "isActive": true,
            "nullField": null,
            "emptyString": ""
        }, null, 2);
    </script>
</body>
</html>

功能说明

这个JSON数据清洗工具提供以下功能:

  1. 格式化JSON:将压缩的或不格式化的JSON数据转换为易读的格式
  2. 移除空值:递归移除JSON中的null值和空字符串
  3. 压缩JSON:将格式化的JSON压缩为紧凑格式
  4. 应用清洗:执行基本的JSON清洗操作
  5. 复制结果:将清洗后的JSON复制到剪贴板
  6. 错误处理:提供详细的错误信息,帮助用户识别JSON格式问题

使用方法

  1. 在左侧文本框中输入或粘贴JSON数据
  2. 选择需要的清洗操作(格式化、移除空值或压缩)
  3. 点击"应用清洗"按钮处理数据
  4. 查看右侧文本框中的清洗结果
  5. 可以使用"复制到剪贴板"按钮复制结果

该工具具有响应式设计,可以在各种设备上使用,并提供了直观的用户界面和状态反馈。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐