По сути, мне нужно, чтобы все содержимое XML-файла находилось в корневом узле, поэтому мне нужно было бы изменить:
<?xml version = "1.0" encoding = "UTF-8"?>
<sss>
<ss id = "01.20211160392320">
<idenSS>
<numSS>
<list>01</list>
<seqOper>20211160392320</seqOper>
</numSS>
</idenSS>
</ss>
</sss>
к чему-то вроде этого:
<?xml version = "1.0" encoding = "UTF-8"?>
<sss>
<sss_ss_idenSS_numSS_list>01</sss_ss_idenSS_numSS_list>
<sss_ss_idenSS_numSS_seqOper>20211160392320</sss_ss_idenSS_numSS_seqOper>
</sss>
Единственный способ, который мне удалось придумать, — чрезвычайно ручной, а XML, с которым я работаю, очень длинный, поэтому я хотел бы построить его несколько динамичным способом, а не явно называть новые теги.
<xsl:stylesheet version = "1.0" xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:output indent = "yes" />
<xsl:template match = "/">
<sss>
<sss_ss_idenSS_numSS_list>
<xsl:value-of select = "sss/ss/idenSS/numSS/list"/>
</sss_ss_idenSS_numSS_list>
<sss_ss_idenSS_numSS_seqOper>
<xsl:value-of select = "sss/ss/idenSS/numSS/seqOper"/>
</sss_ss_idenSS_numSS_seqOper>
</sss>
</xsl:template>
</xsl:stylesheet>
Упс, вы правы на 100%, я не избавился от вложенности. Я изменил желаемый результат в edit.
Хорошо, так где именно вы застряли с этим? И какую версию XSLT вы можете использовать?
К сожалению, я не уверен, какие версии поддерживаются, в этом приложении я видел только версию 1.0, поэтому для безопасности я бы сказал, что 1.0. Моя проблема в том, что единственный способ сделать это чрезвычайно вручную. Добавлю в пост то, что есть.
Посмотрите здесь, как определить ваш процессор и версию, которую он поддерживает: stackoverflow.com/a/25245033/3016153
Я не совсем уверен, что в вашем примере постоянно, а что может измениться. Вот что-то совершенно общее. Чем конкретнее вы сможете это сделать, тем более эффективным он станет.
XSLT 1.0
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:output method = "xml" version = "1.0" encoding = "UTF-8" indent = "yes"/>
<xsl:template match = "/*">
<xsl:copy>
<xsl:for-each select = "//*[not(*)]">
<xsl:variable name = "name">
<xsl:for-each select = "ancestor-or-self::*">
<xsl:value-of select = "name()"/>
<xsl:if test = "position() != last()">-</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:element name = "{$name}">
<xsl:value-of select = "."/>
</xsl:element>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Это идеально, большое спасибо. Не могли бы вы просто объяснить эту часть: select = "//*[not(*)]" ?
//*
выбирает все элементы в любом месте XML-документа. [[not(*)]
ограничивает выбор элементами, не имеющими дочерних элементов, то есть «листовыми» узлами входного дерева. Подробнее: w3.org/TR/1999/REC-xpath-19991116/#path-abbrev
То, что вы описываете, и то, что вы показываете, — две большие разницы. Ваш вывод имеет точно такую же структуру, что и ввод; все, что изменилось, — это имена элементов.