簡體   English   中英

C# XmlReader 無法將“<”讀作 InnerXmlText

[英]C# XmlReader can't read "<" as InnerXmlText

我寫了一個 XML-Parser,在 InnerXml 中我得到了這樣的文本:

<Name ...><<interface>>Employee</Name>
<!-- "<<interface>>Employee" is the InnerXml Text and I need it as string -->

我的閱讀文本代碼如下所示:

     string getName(XmlReader reader)
        {
            string className;
            while (reader.Read())
            {
                if (reader.HasValue)
                {
                    className += reader.Value;
                }
            }
            return className;
        }

但是在我的 XmlTextReader 閱讀此行之后,我遇到了一個異常:

Nachricht: 
    System.Xml.XmlException : Ein Name darf nicht mit dem Zeichen '<', hexadezimaler Wert 0x3C, beginnen.

這意味着,“<”字符不可讀或文本不能以“<”字符開頭。 誰能給我解釋一下這個請? 基本上它自己轉換成這個(在 XML 文件中):

<Name...>&lt;&lt;interface&gt;&gt;Employee</Name> <!-- instead of <<interface>> -->

整個 .grapml 文件(它是一個不同的 xml 符號):(在 y:NodeLabel)

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
  <!--Created by yEd 3.19.1-->
  <key for="port" id="d0" yfiles.type="portgraphics"/>
  <key for="port" id="d1" yfiles.type="portgeometry"/>
  <key for="port" id="d2" yfiles.type="portuserdata"/>
  <key attr.name="url" attr.type="string" for="node" id="d3"/>
  <key attr.name="description" attr.type="string" for="node" id="d4"/>
  <key for="node" id="d5" yfiles.type="nodegraphics"/>
  <key for="graphml" id="d6" yfiles.type="resources"/>
  <key attr.name="url" attr.type="string" for="edge" id="d7"/>
  <key attr.name="description" attr.type="string" for="edge" id="d8"/>
  <key for="edge" id="d9" yfiles.type="edgegraphics"/>
  <graph edgedefault="directed" id="G">
    <node id="n0">
      <data key="d5">
        <y:UMLClassNode>
          <y:Geometry height="116.0" width="131.0" x="1301.3333333333333" y="41.0"/>
          <y:Fill color="#FFCC00" transparent="false"/>
          <y:BorderStyle color="#000000" type="line" width="1.0"/>
          <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="bold" hasBackgroundColor="false" hasLineColor="false" height="33.40234375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="c" textColor="#000000" verticalTextPosition="bottom" visible="true" width="82.052734375" x="24.4736328125" xml:space="preserve" y="3.0">&lt;&lt;interface&gt;&gt;
Employee</y:NodeLabel>
          <y:UML clipContent="true" constraint="" hasDetailsColor="false" omitDetails="false" stereotype="" use3DEffect="true">
            <y:AttributeLabel xml:space="preserve">+name:string
+age:int</y:AttributeLabel>
            <y:MethodLabel xml:space="preserve">getName(value:string):String
getTitle():String
getStaffNo():Int
getRoom():String
getPhone()</y:MethodLabel>
          </y:UML>
        </y:UMLClassNode>
      </data>
    </node>
  </graph>
  <data key="d6">
    <y:Resources/>
  </data>
</graphml>

我的單元測試代碼如下所示:


      public T checkInterfaceOrClass<T> (XmlReader reader, string filepath) where T : BaseModel
        {
            //reader.Settings.IgnoreWhitespace = true;
                    while (reader.Read())
                    {
                        if (getName(reader).Contains("interface"))
                        {
                            InterfaceModel interfaceModel = new InterfaceModel(getName(reader));
                            return (T)Convert.ChangeType(interfaceModel, typeof(InterfaceModel));
                        }
                        else
                        {
                            ClassObject classModel = new ClassObject(getName(reader));
                            return (T)Convert.ChangeType(classModel, typeof(ClassObject));
                        }
                    }
                }
            return null;
        }

根據評論,我寫了一個簡單的片段(使用ReadToDescendant方法跳過文件的整個結構),使用ReadElementContentAsString 方法,效果很好

var xmlReader = XmlReader.Create("...");
bool canRead = xmlReader.ReadToDescendant("y:NodeLabel");
if (canRead)
{
    var content = xmlReader.ReadElementContentAsString();
}

元素內容是(字符串里面有一個\\n

<<interface>>
Employee

您可以輕松地解析此字符串並獲取帶有或不帶有<<interface>>的類名。

僅使用Read方法時,您將獲得相同的結果,如下所示

bool canRead = xmlReader.ReadToDescendant("y:NodeLabel");
if (canRead)
{
    while (xmlReader.Read())
    {
        var content = xmlReader.Value;
    }
}

根據您使用單元測試編輯進行更新。 您不需要使用MoveToContent ,因為ReadElementContentAsString已經讀取了當前元素下的內容。 但主要問題是您多次調用此方法,因為

此方法讀取開始標簽、元素的內容,並將閱讀器移過結束元素標簽。

因此,第二個調用很可能會失敗。 你只需要閱讀一次內容然后解析它,而不是多次閱讀

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM