我试图找出使用VB在Xml文档中存在的特定名称的元素总数。应该是一个足够简单的任务,但我遇到了问题。
我可以使下面的代码工作,但不能将元素名称作为字符串传递(在原始代码中我从一个我要循环的数组中执行此操作),我在视觉中没有收到错误工作室,在编译时或在运行时,它只返回零数量。 我已经删除了原始代码以显示我遇到问题的部分。
以下代码有效。
Dim xmlDoc = XDocument.Load("c:\test\xmlFile.xml")
myXMLRowCount = xmlDoc.Root.Elements.<AIOWEB_tPriceBand>.Count()
MsgBox(myXMLRowCount)
我可以找到将变量作为元素传递的唯一示例是删除。&lt;&gt;并替换为(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 :(得分:2)
我认为,而不是myXMLRowCount = xmlDoc.Root.Elements(myXmlElement).Count()
您需要myXMLRowCount = xmlDoc.Root.Element("dataroot").Elements(myXmlElement).Count()
,以匹配输入样本中的层次结构。或者您至少需要myXMLRowCount = xmlDoc.Root.Elements().Elements(myXmlElement).Count()
。
答案 1 :(得分: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}}方法。