XPathSelectElement给出NullReferenceException

时间:2015-12-17 18:39:56

标签: c# xml xpath unity3d

我在使用XPathSelectElement时遇到问题。我试图通过XPathSelectElement在XML文件中查找元素。

this.xdocument = XDocument.Parse (this.loadDialogues ());
XElement element = this.xdocument.XPathSelectElement ("/dialogues/npc[@npcid='1']/conversation[@id='1']/message[@mid='1']/options/option[@oid='1']/text()");

它给了我这个错误:

  

NullReferenceException:未将对象引用设置为对象的实例

但是当我竞选前。这个查询:

XElement element = this.xdocument.XPathSelectElement ("/dialogues/npc");

一切都好。谁能告诉我有什么问题?在这种情况下,我无法找到有关此错误的任何内容。

我的XML示例文件:

<dialogues>
<!-- Greetings messages -->
<greetings>
    <friendly>
        <text id="1">Witaj przybyszu! W czym mogę Ci pomóc?</text>
        <text id="2">Aniele, co Cię do mnie sprowadza?</text>
        <text id="3">Witaj przybyszu! Czy szukasz czegoś konkretnego?</text>
    </friendly>
    <agressive>
        <text id="1">Czego chcesz? Nie mam ochoty rozmawiać więc się streszczaj.</text>
        <text id="2">Możesz mnie zostawić? To wszystko mnie przerasta...</text>
    </agressive>
</greetings>
<!-- Farewells -->
<farewells>
    <friendly>
        <text id="1">Żegnaj</text>
        <text id="2">Dziękuję, żegnaj</text>
        <text id="3">Do zobaczenia</text>
    </friendly>
    <agressive>
        <text id="1">***** z moich oczu, przybłędo</text>
        <text id="2">Odejdź stąd natychmiast, nie masz tu czego szukać</text>
    </agressive>
</farewells>
<!-- Monologs -->
<monologs>
    <monolog id="1">
        <text id="1">
            Monolog się rozpoczyna...
        </text>
        <text id="2">
            Monolog, część środkowa...
        </text>
        <text id="3">
            Monolog się kończy...
        </text>
    </monolog>
</monologs>
<!-- NPC -->
<npc npcid="1"> 
    <conversation id="1">
        <message mid="1" trigger="greetingRandom(friendly)">                
            <options>
                <option oid="1" nextmid="2">Tak, możesz mi powiedzieć gdzie znajdę Kaplicę?</option>
                <option trigger="endConversationRandom(friendly)"></option>
            </options>
        </message>
        <message mid="2">
            <text>Musisz pójść prosto, u dołu tych schodów będzie strażnik. Powiedz mu, żę Cię przysyłam, wtedy nie powinien robić problemów.</text>
            <options>
                <option oid="1" trigger="endConversation">Dziękuję, żegnaj.</option>
            </options>
        </message>
    </conversation>
</npc>

//编辑:包含更多信息的完整错误

NullReferenceException: Object reference not set to an instance of an object
System.Xml.Linq.XNodeNavigator.get_NodeType ()  
System.Xml.XPath.NodeTypeTest.Match (IXmlNamespaceResolver nsm, System.Xml.XPath.XPathNavigator nav)  
System.Xml.XPath.AxisIterator.MoveNextCore ()  
System.Xml.XPath.BaseIterator.MoveNext ()  
System.Xml.XPath.SimpleSlashIterator.MoveNextCore ()  
System.Xml.XPath.BaseIterator.MoveNext ()  
System.Xml.XPath.SlashIterator.MoveNextCore ()  
System.Xml.XPath.BaseIterator.MoveNext ()  
System.Xml.XPath.SortedIterator..ctor (System.Xml.XPath.BaseIterator iter)  
System.Xml.XPath.ExprSLASH2.Evaluate (System.Xml.XPath.BaseIterator iter)  
System.Xml.XPath.Expression.EvaluateNodeSet (System.Xml.XPath.BaseIterator iter)  
System.Xml.XPath.CompiledExpression.EvaluateNodeSet (System.Xml.XPath.BaseIterator iter)  
System.Xml.XPath.XPathNavigator.Select (System.Xml.XPath.XPathExpression expr, IXmlNamespaceResolver ctx)  
System.Xml.XPath.XPathNavigator.Select (System.Xml.XPath.XPathExpression expr)  
System.Xml.XPath.XPathNavigator.SelectSingleNode (System.Xml.XPath.XPathExpression expression)  
System.Xml.XPath.XPathNavigator.SelectSingleNode (System.String xpath, IXmlNamespaceResolver nsResolver)  
System.Xml.XPath.Extensions.XPathSelectElement (System.Xml.Linq.XNode node, System.String xpath, IXmlNamespaceResolver nsResolver)  
System.Xml.XPath.Extensions.XPathSelectElement (System.Xml.Linq.XNode node, System.String xpath)  
DialogueParser.getConversation (Int32 npcID, Int32 conversationID) (at Assets/Dedicated Assets/Scripts/Dialogue/DialogueParser.cs:38)  
DialogueManager.Awake () (at Assets/Dedicated Assets/Scripts/Dialogue/DialogueManager.cs:33)

2 个答案:

答案 0 :(得分:0)

它被称为XPathSelectElement,因为它允许您选择element个节点。以text()结尾的路径会尝试选择text节点,因此您将始终获得null XElement引用,因为您的路径未选择任何元素节点。因此,使用选择元素节点而不是文本节点的路径。

答案 1 :(得分:0)

最后,我通过使用XMLDocument而不是XDocument解决了这个问题。

在Unity3D中,System.Xml.XPath出了问题。

public class DialogueParser {

    /// <summary>
    /// XMLDocument Instance
    /// </summary>
    private XmlDocument xmldocument;

    public DialogueParser()
    {
        //Populate XMLDocument Instance
        this.xmldocument = new XmlDocument ();
        this.xmldocument.LoadXml (this.loadDialogues());
    }

    /// <summary>
    /// Loads the dialogues from file into TextStream.
    /// </summary>
    /// <returns>dialogues.xml content as text for parsing</returns>
    public string loadDialogues()
    {
        TextAsset dialogues = (TextAsset) Resources.Load<TextAsset> ("dialogues");
        return dialogues.text;
    }

    public void getConversation(int npcID, int conversationID)
    {
        XmlNode el = this.xmldocument.SelectSingleNode (".//dialogues/npc[@npcid='1']/conversation[@id='1']/message[@mid='2']/text/text()");
        Debug.Log (el.Value);
    }
}

使用XMLDocument一切都很好所以我建议使用它而不是XDocument来读取XML文件。