将xdocument元素(不是元素)作为字符串传递

时间:2014-01-16 16:40:11

标签: vb.net variables linq-to-xml elements

我试图找出使用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>

2 个答案:

答案 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}}方法。