Я пытаюсь преобразовать старые XML-файлы в новую и улучшенную структуру. Часть этого нужно мне, чтобы обернуть некоторые свободные элементы в родительский контейнер, а также изменять их детиИспользование XSLT для обертывания элементов, но он не включает последний элемент соответствия
Старая структура
<monograph>
<title>asdf</title>
<dosage.sec id="dosage.sec.1">
<dosage.sec>asgfd</dosage.sec>
<dosage.sec>asgfd</dosage.sec>
</dosage.sec>
<dosage.sec id="dosage.sec.2">
<dosage.sec>asgfd</dosage.sec>
<dosage.sec>asgfd</dosage.sec>
</dosage.sec>
<dosage.sec id="dosage.sec.3">
<dosage.sec>asgfd</dosage.sec>
<dosage.sec>asgfd</dosage.sec>
</dosage.sec>
<products>
<prod>sadf</prod>
<prod>sadf</prod>
</products>
</monograph>
новая структура
<monograph>
<title>asdf</title>
<dosage>
<dosage.sec id="dosage.sec.1">
<dosage.qual>asgfd</dosage.qual>
<dosage.qual>asgfd</dosage.qual>
</dosage.sec>
<dosage.sec id="dosage.sec.2">
<dosage.qual>asgfd</dosage.qual>
<dosage.qual>asgfd</dosage.qual>
</dosage.sec>
<dosage.sec id="dosage.sec.3">
<dosage.qual>asgfd</dosage.qual>
<dosage.qual>asgfd</dosage.qual>
</dosage.sec>
</dosage>
<products>
<prod>sadf</prod>
<prod>sadf</prod>
</products>
</monograph>
я нашел это answer и немного изменил его в соответствии с моими потребностями:
<!-- wrap dosage.sec elements in a dosage container -->
<xsl:template match="node()|@*" name="dosage.sec">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>
<xsl:template match="monograph/dosage.sec[not(preceding-sibling::*[1][self::dosage.sec])]">
<dosage>
<xsl:call-template name="dosage.sec" />
<xsl:apply-templates mode="copy" select="following-sibling::*[1][self::dosage.sec]" />
</dosage>
</xsl:template>
<xsl:template match="monograph/dosage.sec" mode="copy">
<xsl:call-template name="dosage.sec"/>
</xsl:template>
<!-- rename children dosage.sec -->
<xsl:template match="dosage.sec/dosage.sec">
<dosage.qual>
<xsl:apply-templates />
</dosage.qual>
</xsl:template>
Но мой вывод:
<monograph>
<title>asdf</title>
<dosage>
<dosage.sec id="dosage.sec.1">
<dosage.qual>asgfd</dosage.qual>
<dosage.qual>asgfd</dosage.qual>
</dosage.sec>
<dosage.sec id="dosage.sec.2">
<dosage.qual>asgfd</dosage.qual>
<dosage.qual>asgfd</dosage.qual>
</dosage.sec>
<dosage.sec id="dosage.sec.3">
<dosage.qual>asgfd</dosage.qual>
<dosage.qual>asgfd</dosage.qual>
</dosage.sec>
</dosage>
<dosage.sec id="dosage.sec.3">
<dosage.qual>asgfd</dosage.qual>
<dosage.qual>asgfd</dosage.qual>
</dosage.sec>
<products>
<prod>sadf</prod>
<prod>sadf</prod>
</products>
</monograph>
Я использую PHP5 встроенный объект XSLTProcessor - все XML и XSL являются версии 1.0
Ваш XSLT вероятно, будет работать, если вы удалили '[1]' из строки: ' ', но способ, которым вы собираетесь, может быть не лучшим подходом. –
JLRishe
Ответ, на который вы ссылались, касался конкретного сценария, где им необходимо было обернуть элементы, у которых были разные элементы до и после них. У вас есть такое требование, или это так же просто, как ваш пример? – JLRishe
Все элементы dosage.sec должны быть смежными внутри исходного документа (между ними нет других элементов), поэтому оно проще. Я изменил свой пример, поскольку понял, что я не точно изобразил, что у меня есть другие элементы в монографии до и после блока dosage.sec – HorusKol