2012-02-03 60 views
1

我有以下XML:改進代碼找到與使用的AttributeName和節點的節點

<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> 

,我需要從編號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獲取這些數據的任何替代方法?

請建議。

謝謝

+0

如果文檔中的元素的「id」屬性值越來越大,那麼最快速的解決方案之一就是使用XmlReader。此外,存在一個XPath 1.0表達式,其計算結果爲O(N) - 而不是O(N^2),與您的XPath表達式一樣。請確認增加'id'值的屬性。 – 2012-02-04 05:47:35

回答

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

+0

btw,你的問題中的xml示例在Node元素之間有一些垃圾文本數據;這是怎麼回事? – 2012-02-03 07:35:00

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

+0

我用上面的代碼,但同樣的問題。我猜while循環花了很多時間。我如何修改它?我可以修改XPath嗎? – DotnetSparrow 2012-02-03 10:22:05

0

這個XPath表達式的評價只有O(N)的複雜性(線性)對於O(N^2)爲您的初始的XPath表達:

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

這將選擇任何Node元素是XML文檔的頂部元素的子元素和其的屬性id是兩個SPE之間的值規定了下限和上限:分別爲1575

這裏我們假設id屬性Node元素的值是單調遞增的 - 完全和提供的XML文檔一樣。

XSLT - 基於驗證

<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> 

XPath表達式求值和所選擇的節點輸出:

<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> 

時所提供的XML文檔進行該變換

<Node id="15"/> 
<Node id="23"/> 
<Node id="24"/> 
<Node id="25"/> 
<Node id="26"/> 
<Node id="30"/> 
<Node id="31"/> 
<Node id="34"/> 
<Node id="36"/> 
<Node id="37"/> 
<Node id="39"/> 
<Node id="40"/> 
<Node id="41"/> 
<Node id="49"/> 
<Node id="50"/> 
<Node id="51"/> 
<Node id="52"/> 
<Node id="53"/> 
<Node id="61"/> 
<Node id="62"/> 
<Node id="63"/> 
<Node id="69"/> 
<Node id="70"/> 
<Node id="72"/> 
<Node id="74"/> 
<Node id="75"/>