2011-10-31 94 views
3

因此,我需要能夠解析可能包含命名空間前綴的xml文件。我試着用一個示例文件來做這件事,當我嘗試獲取一個節點列表時,即使當我指定一個沒有屬性前綴的節點時,它也會返回null。關於如何使用命名空間前綴解析xml非常困惑

我一直在試圖研究這個問題,它一直回到事實上,沒有定義的名稱空間前綴,它不會工作,所以我添加了我認爲會這樣做的代碼,但它仍然給相同的結果。下面是一些代碼,我補充說:

protected void Page_Load(object sender, EventArgs e) 
{ 
    xml.Load(Server.MapPath("~/SomeLesson/imsmanifest.xml")); 
    populateBaseNodes(); 
} 

private void populateBaseNodes() 
{ 
    treeViewMenu.Nodes.Clear(); // Clear any existing items 
    TreeNode treenode = new TreeNode(); 
    treenode.Text = "organizations"; 
    XmlNodeList baseNodeList; 

    string xmlns = xml.DocumentElement.Attributes["xmlns"].Value; 
    XmlNamespaceManager nsmgr = new XmlNamespaceManager(xml.NameTable); 
    nsmgr.AddNamespace("adlcp", "http://www.adlnet.org/xsd/adlcp_v1p3"); 
    nsmgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); 
    nsmgr.AddNamespace("imscp", "http://www.w3.org/2001/XMLSchema-instance"); 
    nsmgr.AddNamespace("imsss", "http://www.w3.org/2001/XMLSchema-instance"); 
    nsmgr.AddNamespace("schemaLocation", "http://www.w3.org/2001/XMLSchema-instance"); 

    baseNodeList = xml.SelectNodes("/manifest/organizations/organization/item", nsmgr); 

    TextBox1.Text = baseNodeList.Count.ToString(); 

    foreach (XmlNode xmlnode in baseNodeList) 
    { 
     TreeNode treeNodeCatalog = new TreeNode(); 
     treeNodeCatalog.Text = xmlnode.Attributes["identifier"].Value; 
     treeNodeCatalog.SelectAction = TreeNodeSelectAction.Expand; 
     treeViewMenu.Nodes.Add(treeNodeCatalog); 
    } 

    treeViewMenu.CollapseAll(); 
} 

(marc_s)下面是需要被解析有問題的XML:

<manifest identifier="Navigating_in_QuickBooks_-_Introduction_MANIFEST" version="1.3" 
    xmlns="http://www.imsglobal.org/xsd/imscp_v1p1" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:imscp="http://www.imsglobal.org/xsd/imscp_v1p1" 
    xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_v1p3" 
    xmlns:imsss="http://www.imsglobal.org/xsd/imsss" 
    xsi:schemaLocation=" http://www.imsglobal.org/xsd/imscp_v1p1 imscp_v1p1.xsd 
         http://www.imsglobal.org/xsd/imsss imsss_v1p0.xsd 
         http://www.adlnet.org/xsd/adlcp_v1p3 adlcp_v1p3.xsd 
         http://www.adlnet.org/xsd/adlseq_v1p3 adlseq_v1p3.xsd 
         http://www.adlnet.org/xsd/adlnav_v1p3 adlnav_v1p3.xsd"> 

    <metadata> 
    <!-- not relevant here ... --> 
    </metadata> 
    <organizations default="TOC1"> 
    <organization identifier="TOC1"> 
     <title>Navigating in QuickBooks - Introductory Lesson</title> 
     <item identifier="I_SCO0" identifierref="SCO0"> 
      <title>Navigating in QuickBooks - Introductory Lesson</title> 
     </item> 
    </organization> 
    </organizations> 
    <resources> 
    <!-- not relevant here ... --> 
    </resources> 
</manifest> 

回答

4

你不向我們展示你的XML是什麼樣子 - 但有兩個評論:

  1. 你不需要添加xsi前綴,我不知道是什麼schemaLocation前綴應該做的事....

  2. 當你已經定義了模式前綴時,你還需要使用這些前綴在你的XPath中,當然!

同樣,不知道你的XML結構是什麼樣子,我真的不能告訴你需要什麼 - 但是沿着線的東西:

baseNodeList = xml.SelectNodes("/adlcp:manifest/adlcp:organizations/adlcp:organization/imscp:item", nsmgr); 

或任何其他XML命名空間前綴源XML要求。

更新:看到你的XML使得它更清晰:看根節點 - 它有一個默認 XML命名空間(具有xmlns="...."並沒有明確的前綴):

<manifest identifier="Navigating_in_QuickBooks_-_Introduction_MANIFEST" version="1.3" 
    xmlns="http://www.imsglobal.org/xsd/imscp_v1p1" <=== DEFAULT namespace!!! 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:imscp="http://www.imsglobal.org/xsd/imscp_v1p1" 
    xmlns:adlcp="http://www.adlnet.org/xsd/adlcp_v1p3" 
    xmlns:imsss="http://www.imsglobal.org/xsd/imsss" 
    ................> 

這意味着:ALL您的後續節點沒有特定的XML前綴將位於默認名稱空間中。

不幸的是,.NET XML解析與定義了默認的命名空間不帶前綴的問題 - 所以我的最好的解決辦法是創建與默認命名空間的前綴命名空間,然後使用它:

XmlNamespaceManager nsmgr = new XmlNamespaceManager(xml.NameTable); 

// add default namespace, with a prefix for .NET 
nsmgr.AddNamespace("ns", "http://www.imsglobal.org/xsd/imscp_v1p1"); 

baseNodeList = 
    xml.SelectNodes("/ns:manifest/ns:organizations/ns:organization/ns:item", nsmgr); 

待辦事項你現在得到了什麼結果?

+0

對不起,這裏是有一些東西泛型化,以保護無辜的;-) XML –

+0

哎呀,我似乎無法在此添加XML代碼它太大。 –

+0

問題是,在xml中,整個文檔中使用的唯一前綴是我不解析的節點,它只使用adcp。在我解析的節點中沒有前綴,所以在Xpath中使用它是沒有意義的,是嗎? –

0

在您發佈的默認命名空間控制所有在你的樣本文件中的元素的XML是:

xmlns="http://www.imsglobal.org/xsd/imscp_v1p1" 

這個命名空間沒有定義前綴,所以你必須使用一個空白的這個命名空間添加到您的命名空間管理字首。我認爲你應該能夠使用這段代碼來定義默認的命名空間(使用String。空指定空白前綴):

nsmgr.AddNamespace(String.Empty, "http://www.imsglobal.org/xsd/imscp_v1p1"); 
+0

您會*認爲*此方法可行 - 但在.NET XML解析中, **它沒有**;如果你用這個XML文件來嘗試它,即使所有的東西*似乎設置得當,你都會得到一個空的XML節點列表..... –