улучшение кода для поиска узлов с использованием атрибута name и node - PullRequest
1 голос
/ 03 февраля 2012

У меня есть следующий 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 голосов
/ 03 февраля 2012

Вы можете сделать это с 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

Вы можете найти больше информации здесь

0 голосов
/ 04 февраля 2012

Оценка этого выражения XPath имеет только сложность O (N) (линейная) против O (N ^ 2) для вашего исходного выражения XPath:

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

Это выбираетлюбой элемент Node, который является дочерним элементом верхнего элемента документа XML, и значение атрибута id которого находится между двумя указанными нижним и верхним пределами: соответственно 15 и 75.

Здесь мы предполагаем, что значения атрибутов id элементов Node монотонно растут - точно так же, как в предоставленном документе XML.

Проверка на основе XSLT :

<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-документа :

<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 и выводятся выбранные узлы :

<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"/>
0 голосов
/ 03 февраля 2012

Изучение Linq в 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...