c# - 如何使用 C# 将 XML 解析为 lisp 的 S-Expression?
问题描述
我希望能够加载任何 xml 文件并将其转换为 lisp 的 s-expression。有谁知道如何使用 c# 来做到这一点?
我以前没有使用 lisp 或 s-expression 的经验,我的主要问题是我无法弄清楚如何在代码中表示 s-expression 结构。
我会很感激任何提示。
我正在考虑使用 linq to xml 并可能将此 xml 反序列化为 c# 对象,然后将其序列化为 s-expression,但我不确定这是否是正确的方法。
例如,这就是我加载的内容:
<document author="paul@prescod.net">
<para>This is a paragraph <footnote>(just a little one)</footnote>.</para>
<para>Ha! I made you say "underwear".</para>
</document>
这就是我想收到的:
(document author: "paul@prescod.net"
(para "This is a paragraph " (footnote "(better than the one under there)") ".")
(para "Ha! I made you say \"underwear\"."))
解决方案
您可以使用访问者模式XmlReader
来遍历 xml 并生成 S-Expression。此示例生成非常接近的输出(如果需要作为字符串输出,则替换Console
为对象):StringBuilder
var t = @"<document author=""paul@prescod.net"">
<para>This is a paragraph <footnote>(better than the one under there)</footnote>.</para>
<para>Ha! I made you say ""underwear"".</para>
</document>";
var xmlTextReader = XmlTextReader.Create(new StringReader(t));
Visit(xmlTextReader, (XmlNodeType nodeType, XmlReader element) =>
{
switch (nodeType)
{
case XmlNodeType.Element:
Console.WriteLine();
Console.Write(new string('\t', element.Depth));
Console.Write("(" + element.Name);
break;
case XmlNodeType.Text:
if(!string.IsNullOrEmpty(element.Value))
{
Console.Write(@" """ + element.Value.Replace(@"""", @"\""") + @"""");
}
break;
case XmlNodeType.EndElement:
Console.Write(")");
break;
case XmlNodeType.Attribute:
Console.Write(" " + element.Name + @": """ + element.Value.Replace(@"""",@"\""") + @"""");
break;
}
});
...
public static void Visit(XmlReader xmlReader, Action<XmlNodeType, XmlReader> visitor)
{
while (xmlReader.Read())
{
visitor(xmlReader.NodeType, xmlReader);
if (xmlReader.NodeType == XmlNodeType.Element)
{
while (xmlReader.MoveToNextAttribute())
{
visitor(xmlReader.NodeType, xmlReader);
}
}
}
}
推荐阅读
- python - 如何使用 find 方法查找字符串中单词的最后一个字母?
- docker - Vim 将文件路径重新映射到不同的目录
- typo3 - 升级TYPO3 7.6版
- powerbi - 使用switch作为嵌套comaprison的Dax错误
- database - 具有大数据的数据库与文件系统存储
- swift - 带有自定义构造函数的 Swift 枚举
- html - 如何通过“FOR”属性定位(或聚焦)多个输入
- python - 在每行的开头添加前缀不起作用
- android-management-api - Android 管理 API 供私人使用?
- android - RxJava2 - 将多个 Singles 发出的结果组合成一个 Map