生成在HTML中有效的System.Xml.XmlDocument.OuterXml()输出

时间:2009-11-29 22:51:55

标签: c# xml

System.Xml.XmlDocument.OuterXml()将生成(例如)

<list id="myBooks">
  <book id="123" name="XML for muppets" />
  <book id="456" name="HTML for fools" />
</list>

如果你想将这个xml嵌入到HTML页面中,那么它在IE中可以正常工作(因为xml数据岛是html标准的扩展)

但是对于Firefox,您需要使用类似

的内容加载此unknown html tag that happens to contain xml into a DOMParser
var list = document.getElementById("myBooks");
var doc = new DOMParser().parseFromString(list.outerHTML);

但是因为HTML firefox中的<tag /> is not == <tag></tag>会将list.outerHTML视为

<list>
  <book id="123" name="XML for muppets">
     <book id="456" name="HTML for fools">
     </book>
  </book>
</list>

那么如何让XmlDocument.OuterXml()输出xml将是完整的结束标记而不是简写?

编辑 - 添加示例以说明

<html><body>
<xml id="myBooks">
<list>
  <book id="123" name="XML for muppets" />
  <book id="456" name="HTML for fools" />
</list>
</xml>
<script>
var oXml = document.getElementById("myBooks");
alert(oXml.innerHTML);
</script>
</body></html>

2 个答案:

答案 0 :(得分:3)

我很困惑。是什么让你觉得Firefox无法解释自动关闭的XML标签?每个主要浏览器(包括Firefox)都支持XHTML,允许您在没有内容的任何地方使用这种自动关闭标签。为什么XML数据岛会有所不同?

此外,您可能希望使用XmlTextWriter写入StringWriter或其他东西。您可以使用XmlTextWriter配置XmlWriterSettings,指定可以提供更多类似HTML的输出的XmlOutputMethod Html。

更新的 不幸的是我刚测试了这个,而OutputMethod属性有一个内部setter。但出于好奇,我使用反射来设置它,它确实改变了XML输出,使得自闭标签变成了单独的关闭标签。代码如下。

var stream = new System.IO.StringWriter();
var xmldoc = new System.Xml.XmlDocument();
xmldoc.LoadXml("<root><child><grandchild /></child><child /></root>");

var settings = new System.Xml.XmlWriterSettings();
var propInfo = settings.GetType().GetProperty("OutputMethod");
propInfo.SetValue(settings, System.Xml.XmlOutputMethod.Html, null);
var writer = System.Xml.XmlWriter.Create(stream, settings);

xmldoc.Save(writer);

stream.ToString().Dump();

答案 1 :(得分:1)

这有点像kludge,但是在任何空节点中都会添加一个空格,所以会改变

<book id="123" name="XML for muppets" />

<book id="123" name="XML for muppets"> </book>

期待出现在DailyWTF上!

addSpaceToEmptyNodes(xmlDoc.FirstChild);

private void addSpaceToEmptyNodes(XmlNode node)
    {
        if (node.HasChildNodes)
        {
            foreach (XmlNode child in node.ChildNodes)
                addSpaceToEmptyNodes(child);
        }
        else         
            node.InnerText = " ";
    }