XPath для поиска строчек в модели CALS

Я строю процесс, который проходит через большую коллекцию XML-файлов, ищет таблицы моделей CALS (большинство файлов содержат хотя бы один) и затем сохраняет табличные данные обратно в базу данных. Во-первых, многие из этих таблиц будут иметь разные структуры, но я хочу использовать базу данных для анализа общности структуры. Ниже приведен (неполный) фрагмент из файла примера.

   <table frame="none">
        <tgroup cols="6" colsep="0" rowsep="0">
            <colspec colname="1" colnum="1" colwidth="127pt" align="center"/>
            <colspec colname="2" colnum="2" colwidth="39pt" align="center"/>
            <colspec colname="3" colnum="3" colwidth="30pt" align="center"/>
            <colspec colname="4" colnum="4" colwidth="33pt" align="center"/>
            <colspec colname="5" colnum="5" colwidth="33pt" align="center"/>
            <colspec colname="6" colnum="6" colwidth="87pt"/>
            <thead>
                <row valign="bottom">
                    <entry align="center">Product</entry>
                    <entry>SKU</entry>
                    <entry>Length</entry>
                    <entry>Depth</entry>
                    <entry align="center">Weight</entry>
                    <entry align="center">Remarks</entry>
                </row>
                <row valign="bottom">
                    <entry></entry>
                    <entry></entry>
                    <entry>(m)</entry>
                    <entry>(m)</entry>
                    <entry align="center">(kg) </entry>
                    <entry align="center"> </entry>
                </row>
            </thead>
            <tbody>
                <row>
                    <entry align="left" namest="1" nameend="6"><hd4>Whites</hd4></entry>
                </row>
                <row>
                    <entry>Albion</entry>
                    <entry>12345</entry>
                    <entry>398</entry>
                    <entry>15.5</entry>
                    <entry> </entry>
                    <entry>N/A </entry>
                </row>
                <row>
                    <entry>Rotorua</entry>
                    <entry>12346</entry>
                    <entry>398</entry>
                    <entry>15.5</entry>
                    <entry> </entry>
                    <entry> </entry>
                </row>
                <row>
                    <entry>Quintep</entry>
                    <entry>12347</entry>
                    <entry>398</entry>
                    <entry>15.5</entry>
                    <entry> </entry>
                    <entry> </entry>
                </row>

Из-за различий в структурах, с которыми я столкнусь во время этого процесса, я не могу создать схему базы данных в базе данных, в которой будут храниться все эти данные, кроме как сохранить ее как сущности со следующими свойствами:

  • doc_id
  • table_id
  • row_id
  • col_id
  • col_name
  • col_units
  • entry_value

Это позволит мне хранить как строковые, так и числовые значения в виде строк.

Дополнительным свойством, которое требуется в некоторых случаях, является "категория", как определено в строковом ряду в примере выше в tbody/row[1]. Здесь создатель оригинального документа добавил строчку для категоризации строк, следующих непосредственно за:

<row>
    <entry align="left" namest="1" nameend="6"><hd4>Whites</hd4></entry>
</row>

Эти двойные ряды вызывают у меня некоторые трудности. Там, где они происходят, они "классифицируют" строки, следующие до тех пор, пока не произойдет следующий переход.

Мой первоначальный анализ документа показал, что существует ряд возможных "типов" для структуры таблицы по отношению к этим основным элементам:

  • Тип 1. Чтобы в таблицах не возникало проблем - просто и легко обрабатывать
  • Тип 2. Что первая строка в теле - это стрэддл, и что в этом теле есть ноль или более дальнейших переходов.
  • Тип 3. Что таблица содержит стрэдл, но НЕ в первой строке тела

Тип 3 "мог" рассматриваться как две отдельные таблицы, одна из которых относится к типу 1 (все строки до 1-й строки, но исключая 1), и к типу 2 (все строки от 1-го потока вперед)

Таким образом, кажется, что ключ к решению этой проблемы обработки состоит в том, чтобы идентифицировать положение 1-го блока, обрабатывать все (ноль или более строк) перед блоком как тип 1 и обрабатывать все, начиная с блока вперед, как тип 2.

Но у меня возникли некоторые трудности с определением положения там первого стредла. Мое определение 1-го стрэддла - в терминах Xpath -

tbody/row[entry [@nameend &gt; @namest]][1]

Это учитывает возможность того, что стрэддл не всегда имеет ключ из столбца 1 и не всегда распространяется на последний столбец. Обе эти возможности существуют в реальных данных.

Так что моя проблема все еще восходит к определению местоположения 1-го стэддла.

На этой странице перечислено много похожих решений. http://www.dpawson.co.uk/xsl/sect2/flatfile.html.

Но я испытываю затруднения, применяя их к своим экземплярам.

Нечто подобное может работать

<xsl:key name="straddles" match="row[entry[@nameend &gt; @namest]]" use="entry/@namest"/>

Но я не уверен, что использовать для определения атрибута @use ключа?

Когда я пытаюсь определить переменную первого уровня, у меня нет определяющего значения для передачи в функцию key()?

<xsl:variable name="first-straddle" select="table/tgroup/tbody/row[generate-id() = generate-id(key('straddles',?????))]"/>

Как мне найти местоположение первого стэддла?

заранее спасибо

Дополнительные примечания:! [Снимок экрана примера таблицы, отображаемой в браузере] https://dl.dropboxusercontent.com/u/5065004/Screen%20Shot%202014-02-25%20at%2013.54.08.png На приведенном выше снимке экрана показан Пример таблицы отображается в браузере. Последовательности строк "классифицируют" данные в следующих строках - вплоть до следующего уровня. Атрибуты @nasmest и @nameend определяют количество столбцов, пересекаемых заголовком, а не количество строк до следующего перехода. Последнее значение - IMPLICIT в разметке и является оператором XPath, который я ищу. Первый - столбец столбца - является ЯВНЫМ в разметке.

1 ответ

Если я буду следовать этому правильно (большой ЕСЛИ), каждый <entry> можно найти соответствующую категорию, посмотрев на:

<xsl:value-of select="parent::row/preceding-sibling::row[entry[@namest]][1]/entry/hd4"/>

[РЕДАКТИРОВАТЬ ----------------------------------
Чтобы уточнить: это называется из контекста entry, Прочитайте это следующим образом:
1. Подойди к родителю row;
2. Оглянись назад для ближайшего row в том же родителе tbody это имеет entry это имеет namest атрибутов;
3. Получить значение hd4 элемент entry из row найдено в шаге 2.
-------------------------------------------]

Однако кажется, что этого недостаточно; <entry> также необходимо проверить, попадает ли его позиция в родительской строке в диапазон, заданный атрибутами namest и nameend? Если это правильно, то возникает еще один вопрос: возможно ли иметь два сосуществующих "бродяги"? Например, одна категория для столбцов с 1 по 3, а другая категория для столбцов с 5 по 6?


РЕДАКТИРОВАТЬ

Пожалуйста, рассмотрите следующий пример:

<tbody>
    <row>
        <entry namest="1" nameend="3"><hd4>Colors</hd4></entry>
    </row>
    <row>
        <entry>Red</entry>
        <entry>Green</entry>
        <entry>Blue</entry>
    </row>
    <row>
        <entry>Black</entry>
        <entry>White</entry>
    </row>
    <row>
        <entry>Cyan</entry>
        <entry>Magenta</entry>
        <entry>Yellow</entry>
        <entry>Widget(not a color)</entry>
    </row>
    <row>
        <entry namest="4" nameend="5"><hd4>Shapes</hd4></entry>
    </row>
    <row>
        <entry>Brown</entry>
        <entry>Pink</entry>
        <entry>Golden</entry>
        <entry>Circle</entry>
    </row>
    <row>
        <entry>Azure</entry>
        <entry>Grey</entry>
        <entry>Orange</entry>
        <entry>Square</entry>
        <entry>Triangle</entry>
        <entry>Gadget(neither a color nor a shape)</entry>
    </row>
</tbody>

Если я правильно понимаю, вторая "стрельба" НЕ заменяет первую, а дополняет ее. Так что, если мы сейчас попробуем применить вышеупомянутый xPath из контекста:

<entry>Pink</entry>

мы получим неправильный результат (Shapes), потому что мы искали первый предшествующий "straddle" - в то время как мы должны были искать первый предшествующий "straddle", который применяется к столбцу № 2.

Другие вопросы по тегам