Как получить несколько текстовых узлов из XML с помощью XPath, зная, как они были разбиты на части

У меня есть какой-то ужасный xml в следующем формате (анонимно для защиты виновных):

<root>
  <outer attribute="myValue">
    <middle>
      <inner>
        arbitrary text<break />more arbitrary text<break />
      </inner>
    </middle>
  </outer>
  ...
  <outer attribute="myValue">
    <middle>
      <inner>
        arbitrary text<break />more arbitrary text
      </inner>
    </middle>
  </outer>
</root>

Самозакрывающиеся узлы представляют собой разрывы абзаца, в то время как перемещение в полностью отдельные внешние/средние/внутренние деревья не имеет никакого значения (и не должно не приводить к разрыву абзаца).

Простое выражение XPath /*/outer/middle/inner/text() дает мне все текстовые элементы, но я больше не знаю, когда не начинать новый абзац для нового текстового узла. (фактическое выражение далеко не так просто из-за злоупотребления пространством имен и прочего хлама, но в этом суть).

Что было бы лучшим подходом, чтобы обойти этот недостаток и правильно игнорировать разрывы между текстом, не являющиеся абзацами? Есть ли способ, которым я могу также захватить узлы разрыва и идентифицировать их среди текстовых узлов в списке с сохранением порядка?

В качестве дополнительного контекста я работаю в Intersystems Cache, используя API %XML.XPATH.Document (который является оболочкой стандартного SAX, но все еще может иметь ограничения в отношении сложности подхода).

Некоторые ссылки:

http://docs.intersystems.com/cache20131/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&LIBRARY=%25SYS&CLASSNAME=%XML.XPATH.Document

http://docs.intersystems.com/cache20131/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&LIBRARY=%25SYS&CLASSNAME=%25XML.XPATH.ResultHandler


person HonoredMule    schedule 08.08.2013    source источник


Ответы (1)


Вероятно, вы просто хотите выбрать внутренний элемент с помощью //outer/middle/inner/. Значения в

%ListOfObjects(CLASSNAME="%XML.XPATH.RESULT")

будет иметь тип %XML.XPATH.DOMResult, а не %XML.XPATH.ValueResult, как вы получали. Значения %XML.XPATH.DOMResult будут представлять поддерево модели DOM, содержащее как произвольные текстовые узлы, так и узлы «разрыва».

Класс %XML.XPATH.Document имеет метод Example2, который как бы иллюстрирует. Возможно, вы захотите поиграть с его подклассом, который переопределяет блок XData "ExampleXML" с некоторыми дополнительными промежуточными узлами, а также копирует Example2 с выражением XPATH, которое возвращает целое поддерево. Это должно прояснить, как подойти к вашей реальной более сложной проблеме.

person psr    schedule 08.08.2013
comment
Отлично, утром первым делом попробую. К вашему сведению, * действительно не требуется в этом примере, но деталь, которую я не учел в рамках этого вопроса. Фактические выражения должны иметь дело с непоследовательно определенными пространствами имен, непоследовательным использованием пространства имен по умолчанию и узлами, которые принадлежат другому пространству имен (по умолчанию) в зависимости от содержимого бесполезного хлама, который добавляется к дереву xml, поступает из несвязанных источников и модифицирует пространство имен по умолчанию в корневом узле по пути. о_О - person HonoredMule; 09.08.2013