В то время как , что вызывает NullReferenceExceptions и подходит к avoid / fix , такое исключение было рассмотрено в других ответах, что многие программисты не имеют " t узнал еще, как независимо отлаживать такие исключения во время разработки.
В Visual Studio это обычно легко благодаря Visual Studio Debugger .
Во-первых, убедитесь, что правильная ошибка будет обнаружена - см. . Как разрешить нарушение «Исключение System.NullReferenceException» в VS2010? Примечание1
Затем либо Начать с отладки (F5) , либо Приложить [отладчик VS] к запуску процесса . Иногда может быть полезно использовать Debugger.Break
, в котором будет предложено запустить отладчик.
Теперь, когда NullReferenceException выбрано (или необработанно), отладчик остановится ( помните правило, указанное выше?) в строке, на которой произошло исключение. Иногда ошибка может быть легко обнаружена.
Например, в следующей строке единственный код, который может , вызывает исключение, если myString
имеет значение null. Это можно проверить, посмотрев окно Watch или выполнив выражения в окне Immediate Window .
var x = myString.Trim();
В более сложных случаях, таких как следуя ниже, вам нужно будет использовать один из методов выше (Watch или Immediate Windows) для проверки выражений, чтобы определить, было ли str1
пустым или если str2
имеет значение null.
var x = str1.Trim() + str2.Trim();
Once , где было выбрано исключение, это обычно тривиально по отношению к разуму назад, чтобы выяснить, где введенное значение null было [неправильно] -
. Найдите время, необходимое для понимания причина исключения. Проверьте нулевые выражения. Проверьте предыдущие выражения, которые могли бы привести к таким нулевым выражениям. Добавьте контрольные точки и, по мере необходимости, пройдите через программу. Используйте отладчик.
1 Если Break on Throws слишком агрессивен и отладчик останавливается на NPE в библиотеке .NET или сторонних разработчиков, Break на User-Unhandled можно использовать для ограничения выловленных исключений. Кроме того, VS2012 представляет Just My Code , который я рекомендую также включить.
Если вы отлаживаете с включенным Just My Code, поведение немного отличается. При включенном Just My Code отладчик игнорирует исключения, связанные с привилегиями обычного языка (CLR) первого шанса, которые выходят за пределы My Code и не проходят через My Code
blockquote>
Чтобы изменить значение tag
на 2
и tag1
на 3
, используя XMLStarlet :
xmlstarlet ed \
-u '/root/tag' -v 2 \
-u '/root/tag1' -v 3 \
<old.xml >new.xml
Использование ввода образца:
xmlstarlet ed \
-u '/root/tag' -v 2 \
-u '/root/tag1' -v 3 \
<<<'<root><tag>1</tag><tag1>2</tag1></root>'
... испускается как выход:
<?xml version="1.0"?>
<root>
<tag>2</tag>
<tag1>3</tag1>
</root>
Вы можете использовать команду xsltproc
(из пакета xsltproc
в дистрибутивах на основе Debian) со следующим листом XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:param name="tagReplacement"/>
<xsl:param name="tag1Replacement"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tag">
<xsl:copy>
<xsl:value-of select="$tagReplacement"/>
</xsl:copy>
</xsl:template>
<xsl:template match="tag1">
<xsl:copy>
<xsl:value-of select="$tag1Replacement"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Затем используйте команду:
xsltproc --stringparam tagReplacement polop \
--stringparam tag1Replacement palap \
transform.xsl input.xml
Или вы также можете использовать регулярные выражения, но изменение XML через регулярные выражения - это чистое зло:)
my $ 0.02 в python, потому что на каждом сервере вы когда-либо входите в
import sys, xml.etree.ElementTree as ET
data = ""
for line in sys.stdin:
data += line
tree = ET.fromstring(data)
nodeA = tree.find('.//tag')
nodeB = tree.find('.//tag1')
tmp = nodeA.text
nodeA.text = nodeB.text
nodeB.text = tmp
print ET.tostring(tree)
, это читается из stdin, поэтому вы можете использовать его следующим образом:
$ echo '<node><tag1>hi!</tag1><tag>this</tag></node>' | python xml_process.py
<node><tag1>this</tag1><tag>hi!</tag></node>
EDIT - вызов принят
Вот работающая реализация xmllib (должна вернуться к python 1.6). Поскольку я думал, что было бы более интересно пробить глаза вилкой. Единственное, что я могу сказать об этом, это работает для данного варианта использования.
import sys, xmllib
class Bag:
pass
class NodeSwapper(xmllib.XMLParser):
def __init__(self):
print 'making a NodeSwapper'
xmllib.XMLParser.__init__(self)
self.result = ''
self.data_tags = {}
self.current_tag = ''
self.finished = False
def handle_data(self, data):
print 'data: ' + data
self.data_tags[self.current_tag] = data
if self.finished:
return
if 'tag1' in self.data_tags.keys() and 'tag' in self.data_tags.keys():
b = Bag()
b.tag1 = self.data_tags['tag1']
b.tag = self.data_tags['tag']
b.t1_start_idx = self.rawdata.find(b.tag1)
b.t1_end_idx = len(b.tag1) + b.t1_start_idx
b.t_start_idx = self.rawdata.find(b.tag)
b.t_end_idx = len(b.tag) + b.t_start_idx
# swap
if b.t1_start_idx < b.t_start_idx:
self.result = self.rawdata[:b.t_start_idx] + b.tag + self.rawdata[b.t_end_idx:]
self.result = self.result[:b.t1_start_idx] + b.tag1 + self.result[b.t1_end_idx:]
else:
self.result = self.rawdata[:b.t1_start_idx] + b.tag1 + self.rawdata[t1_end_idx:]
self.result = self.result[:b.t_start_idx] + b.tag + self.rresult[t_end_idx:]
self.finished = True
def unknown_starttag(self, tag, attrs):
print 'starttag is: ' + tag
self.current_tag = tag
data = ""
for line in sys.stdin:
data += line
print 'data is: ' + data
parser = NodeSwapper()
parser.feed(data)
print parser.result
parser.close()
Поскольку вы даете пример sed
в одном из комментариев, я предполагаю, что вы хотите получить чистое решение bash?
while read input; do
for field in tag tag1; do
case $input in
*"<$field>"*"</$field>"* )
pre=${input#*"<$field>"}
suf=${input%"</$field>"*}
# Where are we supposed to be getting the replacement text from?
input="${input%$pre}SOMETHING${input#$suf}"
;;
esac
done
echo "$input"
done
Это совершенно неинтеллектуально и, очевидно, работает только на хорошо сформированном входе с начальным тегом и конечным тегом в одной строке, вы не можете иметь несколько экземпляров одного и того же тега в одной строке, список тэгов для замещения жестко закодирован и т. д.
I не может представить ситуацию, когда это было бы действительно полезно, и предпочтительнее либо сценария, либо надлежащего XML-подхода.