私は、ユーザーが XML ファイルを開き、その XML ファイルを編集して保存できるようにする ASP.Net の XML エディターに取り組んでいます。ユーザーがファイルを保存しようとした場合を除いて、すべてが機能しますが、新しく編集されたバージョンではなく、読み込まれたコンテキストからファイルが保存されます。
FileUpload コントロールは現在 IE でのみ機能しますが、これが完全に機能するようになったら、他の Web アプリからディレクトリを渡す予定なので、後で必要になることはありません。
CSS:
#lineNum
{
min-width:30px;
float:left;
color:#F8F8F2;
border-right:1px solid #F8F8F2;
margin-right:10px;
/*
UNSELECTABLE
*/
-moz-user-select: -moz-none;
-khtml-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
}
#editor
{
width:100%;
}
.tagName
{
color:#f92772;
}
.tagVal
{
color:#fd9620;
}
.attrName
{
color:#bce9fd;
}
.attrVal
{
color:#bc95ff;
}
.comment
{
color:#75715e !important;
}
body
{
background-color:#272822;
font-size: 12px;
font-family: Menlo;
color: orange;
}
a
{
color:#bce9fd;
}
C#:
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace XML
{
public partial class index : System.Web.UI.Page
{
public static bool comment;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void menu_MenuItemClick(object sender, MenuEventArgs e)
{
fileUp.Visible = false;
switch (e.Item.Text)
{
case "Open":
fileUp.Visible = true;
break;
case "Save":
saveXml(fileContents.Text);
break;
}
}
protected void openFile_Click(object sender, EventArgs e)
{
if (getFile.HasFile)
{
lblFileLoc.Text = getFile.PostedFile.FileName;
/*lblFileLoc.Text = Server.MapPath(@".\tmp\temp.xml");
getFile.SaveAs(lblFileLoc.Text);*/
lblFileName.Text = getFile.FileName;
lblStat.Text = "Current File: <a href='" + lblFileLoc.Text + "'>" + lblFileName.Text + "</a>";
fileUp.Visible = false;
fileContents.Text = "<pre contenteditable='true'>";
lineNum.InnerText = "\n\n";
string[] xml = File.ReadAllLines(lblFileLoc.Text);
comment = false;
for (int i = 1; i <= xml.Length; i++)
{
lineNum.InnerText += i + "\n";
fileContents.Text += highlightLine(xml[i - 1]);
}
fileContents.Text += "</pre>";
}
}
public void saveXml(string xml)
{
xml = xml.Replace("<XMP class='comment'>", "");
xml = xml.Replace("<XMP class='attrName'>", "");
xml = xml.Replace("<XMP class='attrVal'>", "");
xml = xml.Replace("<XMP class='tagName'>", "");
xml = xml.Replace("<XMP class='tagVal'>", "");
xml = xml.Replace("</XMP>", "");
xml = xml.Replace("<pre contenteditable='true'>", "");
xml = xml.Replace("</pre>", "");
if (xml.Trim().Length > 0)
File.WriteAllText(lblFileLoc.Text, xml);
}
protected string highlightLine(string line)
{
string hlString = "";
int lastIndex = 0;
while (line.IndexOf('<', lastIndex) > -1)
{
int openStart = (line.Contains("<!--")) ? line.IndexOf("<!--", lastIndex) : line.IndexOf('<', lastIndex);
int openEnd = (line.Contains("-->")) ? line.IndexOf("-->", openStart) : line.IndexOf('>', openStart);
hlString += line.Substring(0, openStart);
if (line.Contains("<!--") || line.Contains("-->"))
{
if (line.Contains("<!--") && line.Contains("-->"))
hlString += "<XMP class='comment'>" + line.Substring(openStart, (openEnd + 3 - openStart));
if (line.Contains("<!--") && !line.Contains("-->"))
{
comment = true;
hlString += "<XMP class='comment'>" + line.Substring(openStart, (line.Length - openStart));
break;
}
if (!line.Contains("<!--") && line.Contains("-->"))
hlString += line.Substring(openStart, (line.Length - openStart));
if (line.Contains("-->"))
{
hlString += "</XMP>";
comment = false;
if (line.Substring((line.Length-3), 3) == "-->")
break;
else
lastIndex = openEnd;
}
}
else if (comment)
{
hlString += line.Substring(openStart, (line.Length - openStart));
lastIndex = openEnd;
}
if (!comment)
{
if (line.IndexOf('=', lastIndex) > -1)
{
string[] words = line.Substring(openStart, (openEnd + 1 - openStart)).Split(' ');
foreach (string word in words)
{
if (word.Contains('='))
{
string[] attr = word.Split('=');
hlString += "<XMP class='attrName'>" + attr[0] + "</XMP>=<XMP class='attrVal'>";
if (attr[1].Contains("/>"))
hlString += attr[1].Replace("/>", "") + "</XMP><XMP class='tagName'>/></XMP>";
else if (attr[1].Contains(">"))
hlString += attr[1].Replace(">", "") + "</XMP><XMP class='tagName'>></XMP>";
else if (attr[1].Contains("?>"))
hlString += attr[1].Replace("?>", "") + "</XMP><XMP class='tagName'>?></XMP>";
else
hlString += attr[1] + "</XMP> ";
}
else
hlString += "<XMP class='tagName'>" + word + "</XMP> ";
}
}
else
{
hlString += "<XMP class='tagName'>" + line.Substring(openStart, (openEnd + 1 - openStart)) + "</XMP>";
}
lastIndex = openEnd;
if (!line.Substring(openStart, (lastIndex + 1 - openStart)).Contains('/') && line.IndexOf('<', lastIndex) > -1)
{
int closeStart = line.IndexOf('<', lastIndex);
int closeEnd = line.IndexOf('>', lastIndex + 1);
if (line.Substring(closeStart, (closeEnd + 1 - closeStart)).Contains('/'))
{
hlString += "<XMP class='tagVal'>" + line.Substring((lastIndex + 1), (closeStart - lastIndex - 1)) + "</XMP>";
hlString += "<XMP class='tagName'>" + line.Substring(closeStart, (closeEnd + 1 - closeStart)) + "</XMP>";
lastIndex = closeEnd;
}
}
}
}
return hlString + "\n";
}
}
}
ASP:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="index.aspx.cs" Inherits="XML.index" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link href="styles/main.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="form" runat="server">
<div>
<asp:Menu ID="menu" runat="server" Orientation="Horizontal"
onmenuitemclick="menu_MenuItemClick" BackColor="#272822" ForeColor="orange">
<DynamicMenuItemStyle BackColor="#272822" ForeColor="orange" />
<Items>
<asp:MenuItem Text="File">
<asp:MenuItem Text="Open" Value="Open"></asp:MenuItem>
<asp:MenuItem Text="Save" Value="Save"></asp:MenuItem>
</asp:MenuItem>
</Items>
</asp:Menu>
<asp:Label ID="lblStat" runat="server" />
<asp:Label ID="lblFileName" runat="server" Visible="False" />
<asp:Label ID="lblFileLoc" runat="server" Visible="False" />
<br />
<div id="fileUp" runat="server" visible="False">
<asp:FileUpload ID="getFile" runat="server"></asp:FileUpload>
<asp:Button ID="openFile" Text="Open" runat="server" onclick="openFile_Click"/>
</div>
<div id="editor">
<pre id="lineNum" runat="server"></pre>
<pre>
<asp:Literal ID="fileContents" runat="server"></asp:Literal>
</pre>
</div>
</div>
</form>
</body>
</html>