【问题标题】:How can I display XML with WebBrowser control?如何使用 WebBrowser 控件显示 XML?
【发布时间】:2011-03-01 16:47:48
【问题描述】:

我有一个包含xmlstring。我想用它设置 WebBrowser 控件的值并显示为xml

我可以使用browser.DocumentText 设置值,但我如何让它显示为 XML 呢?

【问题讨论】:

  • 您希望它像 IE 一样显示(使用显示分层视图的 xsl 样式表)还是只是纯 xml 文本?
  • @Simon:就像 IE 一样。对于纯文本,我可以输入 TextBox,使用 WebBrowser 控件没有意义。

标签: c# xml winforms


【解决方案1】:

为@PaoloFalabella 建议的第一个解决方案提供一些代码(即将字符串内容写入临时 xml 文件并导航到它):

//create a random temporary file with an .xml file extension
var path = Path.GetTempPath();
var fileName = Guid.NewGuid().ToString() + ".xml";
var fullFileName = Path.Combine(path, fileName);
//write the contents of your xml string to the temporary file we just created
File.WriteAllText(fullFileName, xmlText); //xmlText is your xml string
//"navigate" to the file
webBrowser.Navigate(fullFileName); //webBrowser is your WebBrowser control

【讨论】:

  • 这将只显示 xml 内部内容,而不是整个 xml 标签
  • @nicolas2008 我不太确定你在说什么,但我在我只是在休息 (swensensoftware.com/im-only-resting) 中使用了这种方法,它可以正常工作(完整的 XML 文档像 IE 一样显示显示任何 XML 文档)。
  • 效果很好。只需要将文本写入文件,并传入<?xml ... encoding="..." ?> 中声明的匹配Encoding 以使其显示(否则WebBrowser 将显示错误页面)。
  • 完美。不是那么优雅,因为它创建了一个文件,但至少它可以工作,而且它比 XSL 转换解决方案工作得更好。不要挑剔,但我会添加一个 File.Delete(fullFileName);最后...
  • webBrowser.DocumentCompleted += delegate { File.Delete(fullFileName); };
【解决方案2】:

这里有一个很好的链接:Displaying XML in the .NET WebBrowser Control

public XmlDocument DocumentXml
{
  set
  {
    Stream s = <defaultss.xsl from embedded resource file>

    XmlReader xr = XmlReader.Create(s);
    XslCompiledTransform xct = new XslCompiledTransform();
    xct.Load(xr);

    StringBuilder sb = new StringBuilder();
    XmlWriter xw = XmlWriter.Create(sb);
    xct.Transform(value, xw);

    this.DocumentText = sb.ToString();
  }
}

【讨论】:

  • 将相关代码添加到您的答案中,以防链接失效。
【解决方案3】:

在这里,我提供了在 WebBrowser 控件中显示 XML 文件的分步解决方案。

  1. 在 WinForm 中添加 WebBrowser 控件。
  2. 在源文件夹中的某处找到 defaultss.xsl。
  3. 并复制下面的方法。

    private void DisplayXml()
    {
        string xmlString = "<Person><Name>Fawad</Name><Age>23</Age></Person>";
    
        // Load the xslt used by IE to render the xml
        XslCompiledTransform xTrans = new XslCompiledTransform();
        xTrans.Load(Path.Combine(new DirectoryInfo(Environment.CurrentDirectory).Parent.Parent.FullName, @"resources\defaultss.xsl"));
    
        // Read the xml string.
        StringReader sr = new StringReader(xmlString);
        XmlReader xReader = XmlReader.Create(sr);
    
        // Transform the XML data
        MemoryStream ms = new MemoryStream();
        xTrans.Transform(xReader, null, ms);
    
        ms.Position = 0;
    
        // Set to the document stream
        webBrowser1.DocumentStream = ms;
    }
    

我在这里复制“defaultss.xsl”的内容给那些在任何地方都找不到的人。只需简单地将其粘贴到记事本文件中,并将其保存为文件夹“资源”中的 xsl 格式,或将其命名为您想要的任何名称。

<!--
 |
 | XSLT REC Compliant Version of IE5 Default Stylesheet
 |
 | Original version by Jonathan Marsh (jmarsh@xxxxxxxxxxxxx)
 | http://msdn.microsoft.com/xml/samples/defaultss/defaultss.xsl
 |
 | Conversion to XSLT 1.0 REC Syntax by Steve Muench (smuench@xxxxxxxxxx)
 |
 +-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- Add doctype attributes to keep IE happy -->
  <xsl:output indent="no"
                method="html"
                doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
                doctype-system="http://www.w3.org/tr/xhtml1/DTD/xhtml1-transitional.dtd" />
  <xsl:template match="/">
    <HTML>
      <HEAD>
        <SCRIPT>
          <xsl:comment>
            <![CDATA[
                  function f(e){
                     if (e.className=="ci") {
                       if (e.children(0).innerText.indexOf("\n")>0) fix(e,"cb");
                     }
                     if (e.className=="di") {
                       if (e.children(0).innerText.indexOf("\n")>0) fix(e,"db");
                     } e.id="";
                  }
                  function fix(e,cl){
                    e.className=cl;
                    e.style.display="block";
                    j=e.parentElement.children(0);
                    j.className="c";
                    k=j.children(0);
                    k.style.visibility="visible";
                    k.href="#";
                  }
                  function ch(e) {
                    mark=e.children(0).children(0);
                    if (mark.innerText=="+") {
                      mark.innerText="-";
                      for (var i=1;i<e.children.length;i++) {
                        e.children(i).style.display="block";
                      }
                    }
                    else if (mark.innerText=="-") {
                      mark.innerText="+";
                      for (var i=1;i<e.children.length;i++) {
                        e.children(i).style.display="none";
                      }
                    }
                  }
                  function ch2(e) {
                    mark=e.children(0).children(0);
                    contents=e.children(1);
                    if (mark.innerText=="+") {
                      mark.innerText="-";
                      if (contents.className=="db"||contents.className=="cb") {
                        contents.style.display="block";
                      }
                      else {
                        contents.style.display="inline";
                      }
                    }
                    else if (mark.innerText=="-") {
                      mark.innerText="+";
                      contents.style.display="none";
                    }
                  }
                  function cl() {
                    e=window.event.srcElement;
                    if (e.className!="c") {
                      e=e.parentElement;
                      if (e.className!="c") {
                        return;
                      }
                    }
                    e=e.parentElement;
                    if (e.className=="e") {
                      ch(e);
                    }
                    if (e.className=="k") {
                      ch2(e);
                    }
                  }
                  function ex(){}
                  function h(){window.status=" ";}

                  document.onclick=cl;
              ]]>
          </xsl:comment>
        </SCRIPT>
        <STYLE>
          BODY {font:small 'Verdana'; margin-right:1.5em; margin-top: 44px;}
          .c  {cursor:hand}
          .b  {color:red; font-family:'Courier New'; font-weight:bold;
          text-decoration:none}
          .e  {margin-left:1em; text-indent:-1em; margin-right:1em}
          .k  {margin-left:1em; text-indent:-1em; margin-right:1em}
          .t  {color:#990000}
          .xt {color:#990099}
          .ns {color:red}
          .dt {color:green}
          .m  {color:blue}
          .tx {font-weight:bold}
          .db {text-indent:0px; margin-left:1em; margin-top:0px;
          margin-bottom:0px;padding-left:.3em;
          border-left:1px solid #CCCCCC; font:x-small Courier}
          .di {font:x-small Courier}
          .d  {color:blue}
          .pi {color:blue}
          .cb {text-indent:0px; margin-left:1em; margin-top:0px;
          margin-bottom:0px;padding-left:.3em; font:x-small Courier;
          color:#888888}
          .ci {font:x-small Courier; color:#888888}
          PRE {margin:0px; display:inline}

          .label {padding-left:20px; vertical-align: middle}
          .validation {color: white; padding: 3px; margin: 5px 5px 5px 5px; text-indent: 0}
          .summary {position: fixed; top: 0; left: 0; margin: 0px; padding-top: 10px; width: 100%; height: 32px; font-size: 12pt; vertical-align: middle;border-bottom: 2px solid black}
          .nav {float: right; padding-right:20px;}
          .failure {background: red;}
          .success {background: green;}
          .warning {background: yellow; color: black}
          .selected {font-weight: bold; text-indent: 1em}
        </STYLE>
      </HEAD>
      <BODY class="st">
        <xsl:apply-templates/>
      </BODY>
    </HTML>
  </xsl:template>

  <!-- Render the schema summary
         Include jquery from CDN and render a title bar across top -->
  <xsl:template match="processing-instruction('schemaSummary')">
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <div id="schemaSummary" class="validation summary">
      <span class="label">
        <xsl:value-of select="." />
      </span>
      <span class="nav">
        <button id="prev">&lt;&lt;</button>
        <button id="next">>></button>
      </span>
    </div>
  </xsl:template>

  <!-- Handle the schemaValid processing instruction 
         This sets up a document.ready routine that 
         colour codes a visual queue i.e. a green title bar.
    -->
  <xsl:template match="processing-instruction('schemaValid')">
    <script>
      $(document).ready(function() {
      $("#schemaSummary").addClass("success")
      $("button").css("display", "none");
      });
    </script>
  </xsl:template>

  <!-- Handle the schemaInvalid processing instruction
         Renders a red title bar with navigation controls to
         step through the errors.    
     -->
  <xsl:template match="processing-instruction('schemaInvalid')">
    <script>
      <![CDATA[
            var index = -1;
            var errors = $("div.failure");
            var offsetFromTop = $("#schemaSummary").outerHeight();
            function nextError(){
                if(index > -1) 
                    $(errors).eq(index).removeClass("selected");
                index ++;
                if(index >= $(errors).size())
                    index = 0;

                $(errors).eq(index).addClass("selected");                                       
                scrollTo($(errors).eq(index), offsetFromTop);
            }
            function prevError(){
                $(errors).eq(index).removeClass("selected");
                index --;
                if(index < 0)
                    index = $(errors).size() - 1;

                $(errors).eq(index).addClass("selected");                                       
                scrollTo($(errors).eq(index), offsetFromTop);               
            }
            function scrollTo(element, offsetFromTop) {
                $('html,body').animate({scrollTop: $(element).offset().top - offsetFromTop},'fast');
            }

            $(document).ready(function() {
                $("#schemaSummary").addClass("warning");
                $("#next").click(function() {
                    nextError();
                });
                $("#prev").click(function() {
                    prevError();
                });
            });
            ]]>
    </script>
  </xsl:template>

  <!-- Add a colour coded bar in situ i.e. where the validation
         error has occured -->
  <xsl:template match="processing-instruction('error')">
    <div class="validation failure">
      <xsl:value-of select="."></xsl:value-of>
    </div>
  </xsl:template>

  <xsl:template match="processing-instruction()">
    <DIV class="e">
      <SPAN class="b">
        <xsl:call-template name="entity-ref">
          <xsl:with-param name="name">nbsp</xsl:with-param>
        </xsl:call-template>
      </SPAN>
      <SPAN class="m">
        <xsl:call-template name="entity-ref">
          <xsl:with-param name="name">lt</xsl:with-param>
        </xsl:call-template>?
      </SPAN>
      <SPAN class="pi">
        <xsl:value-of select="name(.)"/>
      </SPAN>
      <SPAN>
        <xsl:call-template name="entity-ref">
          <xsl:with-param name="name">nbsp</xsl:with-param>
        </xsl:call-template>
        <xsl:value-of select="."/>
      </SPAN>
      <SPAN class="m">
        <xsl:text>?></xsl:text>
      </SPAN>
    </DIV>
  </xsl:template>
  <xsl:template match="processing-instruction('xml')">
    <DIV class="e">
      <SPAN class="b">
        <xsl:call-template name="entity-ref">
          <xsl:with-param name="name">nbsp</xsl:with-param>
        </xsl:call-template>
      </SPAN>
      <SPAN class="m">
        <xsl:call-template name="entity-ref">
          <xsl:with-param name="name">lt</xsl:with-param>
        </xsl:call-template>?
      </SPAN>
      <SPAN class="pi">
        <xsl:text>xml </xsl:text>
        <xsl:for-each select="@*">
          <xsl:value-of select="name(.)"/>
          <xsl:text>="</xsl:text>
          <xsl:value-of select="."/>
          <xsl:text>" </xsl:text>
        </xsl:for-each>
      </SPAN>
      <SPAN class="m">
        <xsl:text>?></xsl:text>
      </SPAN>
    </DIV>
  </xsl:template>
  <xsl:template match="@*">
    <SPAN>
      <xsl:attribute name="class">
        <xsl:if test="xsl:*/@*">
          <xsl:text>x</xsl:text>
        </xsl:if>
        <xsl:text>t</xsl:text>
      </xsl:attribute>
      <xsl:value-of select="name(.)"/>
    </SPAN>
    <SPAN class="m">="</SPAN>
    <B>
      <xsl:value-of select="."/>
    </B>
    <SPAN class="m">"</SPAN>
  </xsl:template>
  <xsl:template match="text()">
    <DIV class="e">
      <SPAN class="b"> </SPAN>
      <SPAN class="tx">
        <xsl:value-of select="."/>
      </SPAN>
    </DIV>
  </xsl:template>
  <xsl:template match="comment()">
    <DIV class="k">
      <SPAN>
        <A STYLE="visibility:hidden" class="b" onclick="return false" onfocus="h()">-</A>
        <SPAN class="m">
          <xsl:call-template name="entity-ref">
            <xsl:with-param name="name">lt</xsl:with-param>
          </xsl:call-template>!--
        </SPAN>
      </SPAN>
      <SPAN class="ci" id="clean">
        <PRE>
          <xsl:value-of select="."/>
        </PRE>
      </SPAN>
      <SPAN class="b">
        <xsl:call-template name="entity-ref">
          <xsl:with-param name="name">nbsp</xsl:with-param>
        </xsl:call-template>
      </SPAN>
      <SPAN class="m">
        <xsl:text>--></xsl:text>
      </SPAN>
      <SCRIPT>f(clean);</SCRIPT>
    </DIV>
  </xsl:template>
  <xsl:template match="*">
    <DIV class="e">
      <DIV STYLE="margin-left:1em;text-indent:-2em">
        <SPAN class="b">
          <xsl:call-template name="entity-ref">
            <xsl:with-param name="name">nbsp</xsl:with-param>
          </xsl:call-template>
        </SPAN>
        <SPAN class="m">
          <xsl:call-template name="entity-ref">
            <xsl:with-param name="name">lt</xsl:with-param>
          </xsl:call-template>
        </SPAN>
        <SPAN>
          <xsl:attribute name="class">
            <xsl:if test="xsl:*">
              <xsl:text>x</xsl:text>
            </xsl:if>
            <xsl:text>t</xsl:text>
          </xsl:attribute>
          <xsl:value-of select="name(.)"/>
          <xsl:if test="@*">
            <xsl:text> </xsl:text>
          </xsl:if>
        </SPAN>
        <xsl:apply-templates select="@*"/>
        <SPAN class="m">
          <xsl:text>/></xsl:text>
        </SPAN>
      </DIV>
    </DIV>
  </xsl:template>
  <xsl:template match="*[node()]">
    <DIV class="e">
      <DIV class="c">
        <A class="b" href="#" onclick="return false" onfocus="h()">-</A>
        <SPAN class="m">
          <xsl:call-template name="entity-ref">
            <xsl:with-param name="name">lt</xsl:with-param>
          </xsl:call-template>
        </SPAN>
        <SPAN>
          <xsl:attribute name="class">
            <xsl:if test="xsl:*">
              <xsl:text>x</xsl:text>
            </xsl:if>
            <xsl:text>t</xsl:text>
          </xsl:attribute>
          <xsl:value-of select="name(.)"/>
          <xsl:if test="@*">
            <xsl:text> </xsl:text>
          </xsl:if>
        </SPAN>
        <xsl:apply-templates select="@*"/>
        <SPAN class="m">
          <xsl:text>></xsl:text>
        </SPAN>
      </DIV>
      <DIV>
        <xsl:apply-templates/>
        <DIV>
          <SPAN class="b">
            <xsl:call-template name="entity-ref">
              <xsl:with-param name="name">nbsp</xsl:with-param>
            </xsl:call-template>
          </SPAN>
          <SPAN class="m">
            <xsl:call-template name="entity-ref">
              <xsl:with-param name="name">lt</xsl:with-param>
            </xsl:call-template>?/
          </SPAN>
          <SPAN>
            <xsl:attribute name="class">
              <xsl:if test="xsl:*">
                <xsl:text>x</xsl:text>
              </xsl:if>
              <xsl:text>t</xsl:text>
            </xsl:attribute>
            <xsl:value-of select="name(.)"/>
          </SPAN>
          <SPAN class="m">
            <xsl:text>></xsl:text>
          </SPAN>
        </DIV>
      </DIV>
    </DIV>
  </xsl:template>
  <xsl:template match="*[text() and not (comment() or processing-instruction())]">
    <DIV class="e">
      <DIV STYLE="margin-left:1em;text-indent:-2em">
        <SPAN class="b">
          <xsl:call-template name="entity-ref">
            <xsl:with-param name="name">nbsp</xsl:with-param>
          </xsl:call-template>
        </SPAN>
        <SPAN class="m">
          <xsl:call-template name="entity-ref">
            <xsl:with-param name="name">lt</xsl:with-param>
          </xsl:call-template>
        </SPAN>
        <SPAN>
          <xsl:attribute name="class">
            <xsl:if test="xsl:*">
              <xsl:text>x</xsl:text>
            </xsl:if>
            <xsl:text>t</xsl:text>
          </xsl:attribute>
          <xsl:value-of select="name(.)"/>
          <xsl:if test="@*">
            <xsl:text> </xsl:text>
          </xsl:if>
        </SPAN>
        <xsl:apply-templates select="@*"/>
        <SPAN class="m">
          <xsl:text>></xsl:text>
        </SPAN>
        <SPAN class="tx">
          <xsl:value-of select="."/>
        </SPAN>
        <SPAN class="m">
          <xsl:call-template name="entity-ref">
            <xsl:with-param name="name">lt</xsl:with-param>
          </xsl:call-template>/
        </SPAN>
        <SPAN>
          <xsl:attribute name="class">
            <xsl:if test="xsl:*">
              <xsl:text>x</xsl:text>
            </xsl:if>
            <xsl:text>t</xsl:text>
          </xsl:attribute>
          <xsl:value-of select="name(.)"/>
        </SPAN>
        <SPAN class="m">
          <xsl:text>></xsl:text>
        </SPAN>
      </DIV>
    </DIV>
  </xsl:template>
  <xsl:template match="*[*]" priority="20">
    <DIV class="e">
      <DIV STYLE="margin-left:1em;text-indent:-2em" class="c">
        <A class="b" href="#" onclick="return false" onfocus="h()">-</A>
        <SPAN class="m">
          <xsl:call-template name="entity-ref">
            <xsl:with-param name="name">lt</xsl:with-param>
          </xsl:call-template>
        </SPAN>
        <SPAN>
          <xsl:attribute name="class">
            <xsl:if test="xsl:*">
              <xsl:text>x</xsl:text>
            </xsl:if>
            <xsl:text>t</xsl:text>
          </xsl:attribute>
          <xsl:value-of select="name(.)"/>
          <xsl:if test="@*">
            <xsl:text> </xsl:text>
          </xsl:if>
        </SPAN>
        <xsl:apply-templates select="@*"/>
        <SPAN class="m">
          <xsl:text>></xsl:text>
        </SPAN>
      </DIV>
      <DIV>
        <xsl:apply-templates/>
        <DIV>
          <SPAN class="b">
            <xsl:call-template name="entity-ref">
              <xsl:with-param name="name">nbsp</xsl:with-param>
            </xsl:call-template>
          </SPAN>
          <SPAN class="m">
            <xsl:call-template name="entity-ref">
              <xsl:with-param name="name">lt</xsl:with-param>
            </xsl:call-template>/
          </SPAN>
          <SPAN>
            <xsl:attribute name="class">
              <xsl:if test="xsl:*">
                <xsl:text>x</xsl:text>
              </xsl:if>
              <xsl:text>t</xsl:text>
            </xsl:attribute>
            <xsl:value-of select="name(.)"/>
          </SPAN>
          <SPAN class="m">
            <xsl:text>></xsl:text>
          </SPAN>
        </DIV>
      </DIV>
    </DIV>
  </xsl:template>

  <xsl:template name="entity-ref">
    <xsl:param name="name"/>
    <xsl:text disable-output-escaping="yes">&amp;</xsl:text>
    <xsl:value-of select="$name"/>
    <xsl:text>;</xsl:text>
  </xsl:template>
</xsl:stylesheet>

【讨论】:

    【解决方案4】:

    不是特别容易,但可能。要么将字符串保存在 xml 文件中,然后使用 Navigate() 将其加载回来(糟糕...),要么将 xsl 应用于 xml(不开玩笑!),像 IE 浏览器一样呈现它。

    见:

    http://social.msdn.microsoft.com/Forums/en/winforms/thread/18ca6734-ddb7-4f44-a77c-9a7713dcc2e1

    【讨论】:

      【解决方案5】:

      答案很简单。我们只需要像这样使用 WebBrowser 控件的 DocumentText 属性:

      this.webBrowserControl.DocumentText = varWithXMLString;
      

      我在控件文档中没有找到的一个细节是字符串必须满足以下要求:

      1. 必须是格式良好的 XML 文档
      2. 必须包含 XML 序言:&lt;?xml version="1.0"?&gt;
      3. 必须验证 XML 字符串不包含 UTF-8 BOM 字符(我进行这项研究的原因)。这很难通过 C# 字符串转换来检测,因为它会生成一个不可打印的字符,只有在将字符串转换为字节或 int 数组时才可见

      在下面的 Github 存储库中是我为展示这些验证而开发的示例:https://github.com/batressc/WinFormsWebBrowserXML

      在下面的链接中你可以看到例子的详细开发(西班牙语):http://batrianoworld.batressc.com/2018/07/22/visualizacion-de-xml-utilizando-control-webbrowser-de-windowsforms

      【讨论】:

        【解决方案6】:
        var responseXml = "<ResponseXML> your xml string </ResponseXML>";    
        var path = Path.Combine(Path.GetTempPath(), "Response.xml");    
        var responseXmlDocument = new XmlDocument();
        responseXmlDocument.LoadXml(responseXml);
        responseXmlDocument.Save(path);
        responseWebBrowser.Navigate(path);
        

        【讨论】:

          【解决方案7】:

          我可以使用 C# 将带有样式表的 XML 加载到 Windows 窗体浏览器控件中,如下所示。

          string xmlFile = @".\sample1.xml";
          string xslFile = @".\sample1.xsl";
          
          XslCompiledTransform xslDocument = new XslCompiledTransform();
          xslDocument.Load(xslFile);
          StringWriter stringWriter = new StringWriter();
          XmlWriter xmlWriter = new XmlTextWriter(stringWriter);
          xslDocument.Transform(xmlFile, xmlWriter);
          webDocumentView.DocumentText = stringWriter.ToString(); // webDocumentView is Web Browser Control- System.Windows.Forms.WebBrowser webDocumentView;
          

          如果您在使用此代码时遇到任何问题,请发表评论。

          【讨论】:

            【解决方案8】:

            您不需要保存临时文件,只需执行此操作...

            browserControl.NavigateToString(xml);
            

            【讨论】:

            • 我猜那是 WPF
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-11-25
            • 1970-01-01
            • 2013-04-23
            相关资源
            最近更新 更多