не уверен, если это возможно без того, чтобы пройти через несколько проходов, но я все равно спрошу (мой XSL немного ржавый)XSLT пропустить уже «посещаемые» узлы
У меня есть документ XML, который содержит узлы следующим образом: (! реальный файл содержит множество структурных тегов, взаимозависимостей, ни один из которых циркулярный)
<structures>
<structure id="STRUCT_A">
<field idref="STRUCT_B" name="b"/>
<field idref="STRUCT_C" name="c"/>
<field idref="FIELD_D" name="d"/>
</structure>
<structure id="STRUCT_B">
<field idref="STRUCT_C" name="c"/>
<field idref="FIELD_E" name="e"/>
</structure>
<structure id="STRUCT_C">
<field idref="FIELD_E" name="e"/>
<field idref="FIELD_F" name="f"/>
<field idref="FIELD_G" name="g"/>
</structure>
</structures>
То, что я хочу сделать, это произвести некоторый текст (в данном случае C++ struct
), и очевидным требованием является порядок o е в struct
с, так что мой идеальным выходом будет
struct STRUCT_C
{
FIELD_E e;
FIELD_F f;
FIELD_G g;
};
struct STRUCT_B
{
STRUCT_C c;
FIELD_E e;
};
struct STRUCT_A
{
STRUCT_B b;
STRUCT_C c;
FIELD_D d;
};
Я знаю, что я мог бы использовать вперед декларации и это будет означать, что порядок не имеет значения, однако проблема в том, что там будет «обработка» код рядной в структурах, и для этого потребуется реальное определение.
До сих пор я могу обнаружить, чтобы увидеть, если structure
имеет никаких зависимостей, со следующим битом XSL:
<xsl:for-each select="descendant::*/@idref">
<xsl:variable name="name" select="."/>
<xsl:apply-templates select="//structure[@id = $name]" mode="struct.dep"/>
</xsl:for-each>
(это происходит внутри <xsl:template match="structure">
)
Теперь, теоретически, я мог бы тогда следуйте этой «цепочке» зависимостей и генерируйте struct
s для каждой записи сначала, а затем тот, который я нахожу сейчас, однако, как вы можете себе представить, это создает копии экземпляров той же структуры, что является болью.
Есть ли все-таки, чтобы избежать копий? В принципе, как только структура была посещена, и если мы снова заходим, чтобы не беспокоить вывод кода для нее ... Мне не нужен полный xslt для этого (если только это не тривиально!), А просто любые идеи о подходах ...
Если нет, то я мог бы теоретически обернуть struct
с #ifdef
/#define
/#endif
настороже, так что компилятор использует только первое определение, однако это действительно NASTY! :(
(ПРИМЕЧАНИЯ: XSLT 1.0, xsltproc на Linux: Использование LibXML 20623, 10115 и LibXSLT libexslt 812)
Отличный вопрос, +1. См. Мой ответ для полного и короткого решения. :) –