改进代码以使用attributename和node查找节点

时间:2012-02-03 07:17:47

标签: asp.net xml vb.net xpath

我有以下xml:

<TextWithNodes><Node id="0" />astralis<Node id="8" /> <Node id="9" />ltd<Node id="12" />
<Node id="14" />{<Node id="15" />DOCUMENT<Node id="23" />}<Node id="24" /> <Node id="25" />{<Node id="26" />TYPE<Node id="30" />}<Node id="31" />EX-<Node id="34" />10<Node id="36" />.<Node id="37" />12<Node id="39" /> <Node id="40" />{<Node id="41" />SEQUENCE<Node id="49" />}<Node id="50" />3<Node id="51" /> <Node id="52" />{<Node id="53" />FILENAME<Node id="61" />}<Node id="62" />e<Node id="63" />300201<Node id="69" />_<Node id="70" />ex<Node id="72" />10<Node id="74" />-<Node id="75" />12<Node id="77" />.<Node id="78" />txt<Node id="81" /> </TextWithNodes>

我需要从Id 25中选择节点到id 75.它是XML的一部分。原始XML很长。

我正在使用以下代码:

Dim reader As XmlTextReader = New XmlTextReader(System.Web.HttpContext.Current.Server.MapPath("~/App_Data/gate_xml_output.xml"))

            reader.WhitespaceHandling = WhitespaceHandling.None

            Dim xmlDoc As XmlDocument = New XmlDocument()
            'Load the file into the XmlDocument
            xmlDoc.Load(reader)
            'Close off the connection to the file.
            reader.Close()

  Dim nodeList As XmlNodeList = xmlDoc.SelectNodes("//TextWithNodes/node()[preceding-sibling::Node[@id=" & startNode & "] and following-sibling::Node[@id=" & endNode & "]]")

            Dim sb As StringBuilder = New StringBuilder

            For Each childNode As XmlNode In nodeList
                If childNode.Value IsNot Nothing Then
                    sb.Append(childNode.Value & " ")
                End If
            Next

            ' read the text between these nodes
            ExtractText = sb.ToString

它正在工作但它很慢。从XML获取此数据的任何替代方法?

请建议。

由于

3 个答案:

答案 0 :(得分:0)

探索Linq to XML;它应该更快:http://msdn.microsoft.com/en-us/library/bb387098.aspx

此处也有好消息:http://www.hookedonlinq.com/LINQtoXML5MinuteOverview.ashx

那里有很多信息。

这是一篇关于与xmldoc和xmlreader进行性能比较的文章:http://www.nearinfinity.com/blogs/joe_ferner/performance_linq_to_sql_vs.html

和另一个:http://msdn.microsoft.com/en-us/library/bb387048.aspx

1

答案 1 :(得分:0)

你可以用XPath做到这一点。像这样:

Dim sb As New StringBuilder()
Dim document As New XPathDocument("C:\testfile2.xml")
Dim navigator As XPathNavigator = document.CreateNavigator()
Dim iterator As XPathNodeIterator = navigator.Select("yourPath")
While iterator.MoveNext()
    sb.Append(iterator.Current.Value)
End While

您可以找到更多信息here

答案 2 :(得分:0)

对于原始XPath表达式,此XPath表达式的评估仅具有O(N)复杂度(线性)与O(N ^ 2):

/*/Node[@id >= 15 and not(@id > 75)]

这将选择任何Node元素,该元素是XML文档顶部元素的子元素,其id属性的值在两个指定的下限和上限之间:{{1} }和15

这里我们假设75元素的id属性值单调递增 - 与提供的XML文档完全一样。

基于XSLT的验证

Node

对提供的XML文档执行此转换

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:copy-of select=
  "/*/Node[@id >= 15 and not(@id > 75)]"/>
 </xsl:template>
</xsl:stylesheet>

评估XPath表达式并输出所选节点

<TextWithNodes>
    <Node id="0" />astralis
    <Node id="8" />
    <Node id="9" />ltd
    <Node id="12" />
    <Node id="14" />{
    <Node id="15" />DOCUMENT
    <Node id="23" />}
    <Node id="24" />
    <Node id="25" />{
    <Node id="26" />TYPE
    <Node id="30" />}
    <Node id="31" />EX-
    <Node id="34" />10
    <Node id="36" />.
    <Node id="37" />12
    <Node id="39" />
    <Node id="40" />{
    <Node id="41" />SEQUENCE
    <Node id="49" />}
    <Node id="50" />3
    <Node id="51" />
    <Node id="52" />{
    <Node id="53" />FILENAME
    <Node id="61" />}
    <Node id="62" />e
    <Node id="63" />300201
    <Node id="69" />_
    <Node id="70" />ex
    <Node id="72" />10
    <Node id="74" />-
    <Node id="75" />12
    <Node id="77" />.
    <Node id="78" />txt
    <Node id="81" />
</TextWithNodes>