2014-01-16 39 views
3

我試圖發現,通過使用VB XML文檔中存在的特定名稱的元素的總數。應該是一個簡單的任務,但我遇到了一個問題。通的XDocument元件(未元素)作爲字符串

我可以做下面的代碼的工作,但不能將元素的名字作爲一個字符串(在原來的代碼,我從我想遍歷數組這樣做),我沒有收到錯誤visual studio,在編譯時或運行時,它只返回零數量。 我已將原始代碼縮減爲只顯示我遇到問題的部分。

以下代碼有效。

Dim xmlDoc = XDocument.Load("c:\test\xmlFile.xml") 
    myXMLRowCount = xmlDoc.Root.Elements.<AIOWEB_tPriceBand>.Count() 
    MsgBox(myXMLRowCount) 

我可以找到傳遞變量作爲元素的唯一例子是刪除。 <>並用(MYVARIABLE)取代 - 如下面所示的代碼中,但例如我看到這個上爲元素不元素和不出現的工作是相同的(除非我在命令缺少一個步驟/字符結構體)。

Dim xmlDoc = XDocument.Load("c:\test\xmlFile.xml") 
    Dim myXmlElement As String = "AIOWEB_tPriceBand" 
    myXMLRowCount = xmlDoc.Root.Elements(myXmlElement).Count() 
    MsgBox(myXMLRowCount) 
  • 編輯*

這裏是有問題的XML文件中的削減例子。 我與上面的代碼行,並再次直接參考著作(顯示5種元素),但在第二實施例與可變返回0的元素這裏進行了測試。

<?xml version="1.0" encoding="UTF-8"?> 
<root xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:od="urn:schemas-microsoft-com:officedata"> 
    <xsd:schema> 
     <xsd:element name="dataroot"> 
      <xsd:complexType> 
       <xsd:sequence> 
        <xsd:element ref="AIOWEB_tPriceBand" minOccurs="0" maxOccurs="unbounded"/> 
       </xsd:sequence> 
       <xsd:attribute name="generated" type="xsd:dateTime"/> 
      </xsd:complexType> 
     </xsd:element> 
     <xsd:element name="AIOWEB_tPriceBand"> 
      <xsd:annotation> 
       <xsd:appinfo> 
        <od:index index-name="ProductCode" index-key="ProductCode " primary="no" unique="no" clustered="no"/> 
       </xsd:appinfo> 
      </xsd:annotation> 
      <xsd:complexType> 
       <xsd:sequence> 
        <xsd:element name="ProductCode" minOccurs="0" od:jetType="text" od:sqlSType="nvarchar"> 
         <xsd:simpleType> 
          <xsd:restriction base="xsd:string"> 
           <xsd:maxLength value="50"/> 
          </xsd:restriction> 
         </xsd:simpleType> 
        </xsd:element> 
        <xsd:element name="MinQty" minOccurs="0" od:jetType="longinteger" od:sqlSType="int" type="xsd:int"/> 
        <xsd:element name="MaxQty" minOccurs="0" od:jetType="longinteger" od:sqlSType="int" type="xsd:int"/> 
        <xsd:element name="UnitPrice" minOccurs="0" od:jetType="currency" od:sqlSType="money" type="xsd:double"/> 
       </xsd:sequence> 
      </xsd:complexType> 
     </xsd:element> 
    </xsd:schema> 
    <dataroot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" generated="2014-01-16T12:02:35"> 
     <AIOWEB_tPriceBand> 
      <ProductCode>0000000000001</ProductCode> 
      <MinQty>1</MinQty> 
      <MaxQty>0</MaxQty> 
      <UnitPrice>0.01</UnitPrice> 
     </AIOWEB_tPriceBand> 
     <AIOWEB_tPriceBand> 
      <ProductCode>0000000000002</ProductCode> 
      <MinQty>1</MinQty> 
      <MaxQty>0</MaxQty> 
      <UnitPrice>0.01</UnitPrice> 
     </AIOWEB_tPriceBand> 
     <AIOWEB_tPriceBand> 
      <ProductCode>0000000000003</ProductCode> 
      <MinQty>1</MinQty> 
      <MaxQty>0</MaxQty> 
      <UnitPrice>0.01</UnitPrice> 
     </AIOWEB_tPriceBand> 
     <AIOWEB_tPriceBand> 
      <ProductCode>0000000000004</ProductCode> 
      <MinQty>1</MinQty> 
      <MaxQty>0</MaxQty> 
      <UnitPrice>0.01</UnitPrice> 
     </AIOWEB_tPriceBand> 
     <AIOWEB_tPriceBand> 
      <ProductCode>0000000000005</ProductCode> 
      <MinQty>1</MinQty> 
      <MaxQty>0</MaxQty> 
      <UnitPrice>0.01</UnitPrice> 
     </AIOWEB_tPriceBand> 
    </dataroot> 
</root> 
+0

它適用於我。你能發佈一個可用於重現行爲的示例XML文檔嗎? –

+0

您好史蒂夫,我會得到一個較小的文件,將其裁減5個記錄並去掉敏感信息。謝謝 – user3203148

+1

嗨史蒂夫,我已經將Xml示例添加到了我的原始帖子中。謝謝 – user3203148

回答

2

AIOWEB_tPriceBand該元件不直接位於root元素數量。相反,它們實際上位於/root/dataroot元素下。

第一個代碼示例工作的原因是因爲它正在讀取xmlDoc.Root.Elements.<AIOWEB_tPriceBand>元素。您會注意到它不直接在Root下訪問AIOWEB_tPriceBand元素。而是從Root.Elements訪問它們,它實際上是Root元素的所有子元素的集合。由於datarootRoot元素的子元素,它會尋找他們下存在。爲了使第一個代碼示例模仿第二個,你會需要它這樣寫:

' Won't work because it looks for /root/AIOWEB_tPriceBand 
myXMLRowCount = xmlDoc.Root.<AIOWEB_tPriceBand>.Count() 

來寫它的不易混淆的方式,以使其正常工作,將是這樣的:

' Will work because it looks for /root/dataroot/AIOWEB_tPriceBand 
myXMLRowCount = xmlDoc.Root.<dataroot>.<AIOWEB_tPriceBand>.Count() 

現在,它更清楚爲什麼它是第一個例子是實際工作,現在應該更清楚如何讓第二個例子的工作:

myXMLRowCount = xmlDoc.Root.<dataroot>.Elements(myXmlElement).Count() 

或者,如果你不關心文檔結構中的確切位置,實際上存在的元素,並且你想要做的只是獲得它們的總數,而且它們恰好在文檔中,那麼你可以只需搜索根的任何後代用這個名字,而不是指定路徑向下穿過dataroot元素:由字符串

myXMLRowCount = xmlDoc.Root...<AIOWEB_tPriceBand>.Count() 

或者:

myXMLRowCount = xmlDoc.Root.Descendants(myXmlElement).Count() 

我還要提到的是,你真的應該要使用MessageBox.Show而不是舊的VB6式MsgBox方法。

+1

謝謝,史蒂夫,完美的作品。這真的讓我發瘋,只是看不到問題。 (我已經將任何Msgbox語句更改爲MessageBox btw - 猜測我正在顯示我的年齡...重新培訓的時間 – user3203148

+0

@ user3203148如果您有興趣強制關閉VB6樣式命令(.NET中包含這些命令主要是爲了向後兼容),你可能想嘗試一下,作爲一個學習實驗,從你的項目設置「Imported Namespaces」中刪除'Microsoft.VisualBasic'命名空間。這是所有這些東西都被放置在的命名空間。不幸的是,有一些新的.NET中只包含那些名稱空間中的東西,所以完全不使用命名空間並不總是一種選擇,但它是強制關閉VB特定的東西的好方法。 –

+0

謝謝史蒂夫,我會放棄並看看我如何得到 – user3203148

2

我想,而不是你想要myXMLRowCount = xmlDoc.Root.Element("dataroot").Elements(myXmlElement).Count()myXMLRowCount = xmlDoc.Root.Elements(myXmlElement).Count(),您輸入樣品中的層次結構相匹配。或者您至少需要myXMLRowCount = xmlDoc.Root.Elements().Elements(myXmlElement).Count()

+0

感謝馬丁,這也很完美......非常感謝。 – user3203148