У меня есть старое приложение, разработанное на старой архитектуре, которое мне нужно перенести в современный мир; в старой архитектуре были особенности, которые я не могу воспроизвести. Идея такая: я поставщик данных. У клиентов будут особые требования к формату данных c. Чтобы облегчить это, клиенты создают «xml шаблоны документов», и с помощью этого механизма мое приложение заполняет данные в точном формате, который им нужен. Рассмотрим этот произвольный образец, предоставленный заказчиком xml:
<xml><data><people>
<replacetag1><person><name>$NAME$</name><address>$ADDRESS$</address></person></replacetag1>
</people></data></xml>
Этот документ читается, код находит <replacetag1>
, берет содержимое внутри указанного тега и генерирует <person>
или <person>
s. Это оставляет полное форматирование документа на усмотрение клиента и его требований.
Приложение содержит следующую базовую функцию (vb. net, но могла бы реализовать ее аналогичным образом в c#):
Dim oDoc = XElement.Load(FileName)
For Each oDesc In oDoc.Descendants
If oDesc.Name.LocalName.StartsWith(TagPrefix, StringComparison.OrdinalIgnoreCase) Then
Dim sVal = String.Concat(oDesc.Nodes)
RaiseEvent TagReplace(oDesc.Name.LocalName, sVal)
oDesc.ReplaceWith(sVal)
End If
Next
Вместо того, чтобы искать специально для тега <replacetag1>
, код совпадает с началом имени тега (TagPrefix) в ожидании, что потребуется выполнить несколько замен по нескольким причинам, и все это RaiseEvent / ReplaceWith код работает точно так, как ожидалось, на первом проходе. Если я установил точку останова после oDes c .ReplaceWith, документ (oDo c) в этой точке будет выглядеть идеально.
Но в этот момент из-за изменения базового документа итератор сломается и Я получаю исключение NullReferenceException в «Далее». Из-за этой ошибки я не смог поймать второе появление другого <replacetag1>
(редко, но возможно) или другого типа замены (ie <replacetag2>
) в том же документе. Мне нужно продолжить итерацию остальной части документа, ища больше замен, и нужно, чтобы он был sh изящно.
Это использует Xml .Linq, но DOM может быть лучше для обработки таких типов на - доработка документа «на лету»; Я в лучшем случае новичок в обеих технологиях.
Изменить: Чтобы обрабатывать заменяемые теги, которые выходят из самого контента (а также из-за исходной проблемы), я решил перепроектировать это, чтобы выполнять рекурсивное сканирование и замену внутри самой рекурсивной подпрограммы. Затем весь документ повторно сканируется с самого начала каждый раз, но у него есть возможность обрабатывать заменяющие теги внутри заменяющего содержимого, и он может просто выполнить Exit For
, прежде чем возникнет оскорбительная ошибка:
Dim oDoc = XElement.Load(FileName)
CheckReplacements(oDoc)
Private Sub CheckReplacements(XE As XElement)
For Each oDesc In XE.Descendants
If oDesc.Name.LocalName.StartsWith(TagPrefix, StringComparison.OrdinalIgnoreCase) Then
Dim sVal = String.Concat(oDesc.Nodes)
RaiseEvent TagReplace(oDesc.Name.LocalName, sVal)
oDesc.ReplaceWith(XElement.Parse(sVal))
CheckReplacements(XE)
Exit For
End If
Next
End Sub
Этот метод отлично работает и буду работать над моим решением. Однако, если разметка не помещается в элемент, в который нужно заключить вывод, это не сработает с исключением XmlException в XElement.Parse()
. Любые предложения о том, как лучше обрабатывать sVal
, являющийся либо текстом, либо фрагментом xml, чем также обрабатывать кодировку, как я ожидал?