2014-01-16 2 views
3

Я пытаюсь выяснить общее количество элементов определенного имени, которые существуют в документе Xml, используя VB. Должна быть достаточно простая задача, но я столкнулся с проблемой.передать элементы xdocument (not element) как строку

Я могу сделать следующий код работы, но не могу передать имя элемента в виде строки (в исходном коде я делаю это из массива, который я хочу пропустить), я не получаю ошибку в визуальной студии, во время компиляции или во время выполнения, она просто возвращает нулевое количество. Я вырезал исходный код, чтобы показать только раздел, с которым я столкнулся.

Следующий код работает.

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

Единственный пример, который я могу найти для передачи переменной в качестве элемента, удалив. <> и заменяя на (myVariable) - как показано ниже, но пример, который я видел это для Element not Elements, и, похоже, не работает одинаково (если только мне не хватает указателя/символа в команде состав).

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>. Вы заметите, что он не обращается к элементам AIOWEB_tPriceBand непосредственно под Root. Вместо этого он обращается к ним с Root.Elements, что на самом деле является совокупностью всех дочерних элементов элемента Root. Поскольку dataroot является дочерним элементом элемента Root, он будет искать их под ним.Для того, чтобы сделать первый образец кода имитировать второй, вы нуждались бы написать так:

' 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() 

в качестве альтернативы , если вам все равно, где именно, в структуре документа, что фактически существуют элементы AIOWEB_tPriceBand, и все, что вы хотите сделать, это получить общее количество их, где бы они ни находились в документе, которым они являются, тогда вы можете просто поиск любых потомков корня под этим именем, а не указывать путь вниз через dataroot элемент:

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

Или, по строке:

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

Я должен также упомянуть, что вы действительно должны чтобы использовать MessageBox.Show, а не старый метод MsgBox VB6.

+1

Спасибо, Стив, отлично работает. Это действительно сводило меня с ума, просто не мог понять проблему. (Я изменил любые инструкции Msgbox на MessageBox btw - думаю, я показываю свой возраст ... время для переподготовки. – user3203148

+0

@ user3203148 Если вы заинтересованы в том, чтобы заставить себя работать с командами стиля VB6 (которые включены в .NET прежде всего для обратной совместимости), вы можете попробовать как экспериментальный эксперимент удалить пространство имен Microsoft.VisualBasic из настроек вашего проекта «Импортированные пространства имен». Это пространство имен, в котором находятся все эти вещи. К сожалению, есть некоторые новые .NET - только те вещи, которые также находятся в этом пространстве имен, поэтому полное использование пространства имен не всегда является вариантом, но это хороший способ заставить себя отключить специфические для VB вещи. –

+0

Спасибо Стиву, я дам это и посмотреть, как я нахожусь – user3203148

2

Я думаю, что вместо myXMLRowCount = xmlDoc.Root.Elements(myXmlElement).Count() вы хотите myXMLRowCount = xmlDoc.Root.Element("dataroot").Elements(myXmlElement).Count(), чтобы соответствовать иерархии в вашей входной выборки. Или вам нужно как минимум myXMLRowCount = xmlDoc.Root.Elements().Elements(myXmlElement).Count().

+0

Спасибо Мартину, это тоже отлично работало ... высоко ценится. – user3203148

Смежные вопросы