#xml #xslt #xpath #xslt-1.0
#xml #xslt #xpath #xslt-1.0
Вопрос:
Мне нужно условно объединить два XML-файла с помощью xslt-1.0. Первый файл:
<rootnode>
<section id="1" >
<outer param="p1" >
<inner />
<inner />
</outer>
<outer >
<inner />
</outer>
<outer />
<outer />
</section>
<section id="3" >
<outer >
<inner />
<inner />
<inner />
</outer>
</section>
</rootnode>
Второй файл:
$ cat res.xml
<rootnode>
<section id="1" status="fail">
<outer param="p1" status="fail">
<inner status="fail"/>
<inner status="pass"/>
</outer>
<outer status="pass">
<inner status="pass"/>
</outer>
<outer status="pass"/>
<outer status="fail"/>
</section>
<section id="2" status="fail">
<outer status="fail">
<inner status="pass"/>
<inner status="fail"/>
<inner status="inc"/>
</outer>
</section>
<section id="6" status="inc">
<outer status="inc">
<inner status="inc"/>
</outer>
</section>
</rootnode>
Пока у меня есть этот файл XSLT:
$ cat filter.xsl
<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:strip-space elements="*"/>
<xsl:param name="doc" select="document('in.xml')"/>
<!-- part 1 -->
<xsl:template match="/">
<xsl:variable name="var" select="/rootnode/section" />
<xsl:for-each select="$doc//section[not(@id = $var/@id)] ">
<xsl:copy-of select="."/>
</xsl:for-each>
</xsl:template>
<!-- part 2 -->
<!--xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[@status[not(normalize-space()='fail')]]"/>
<xsl:template match="@*[local-name() = 'status' "/-->
</xsl:stylesheet>
Я использую xsltproc
для обработки файлов
$ xsltproc filter.xsl res.xml
В части 1 будут напечатаны section
узлы, которые находятся внутри in.xml
, а не внутри res.xml
. Если я закомментирую часть 1 и раскомментирую часть 2, я получу узлы, у res.xml
которых есть fail
статус. Мне как-то нужно объединить эти функции, т. Е. Мне нужно получить все section
узлы, которые находятся только в файле in.xml
, и, кроме того, все узлы из res.xml
этого имеют fail
статус. Узлы однозначно идентифицируются по их id
атрибуту в section
.
Для вышеуказанных двух файлов результирующий файл должен выглядеть следующим образом:
$ cat final.xml
<?xml version="1.0" encoding="UTF-8"?>
<rootnode>
<section id="1">
<outer param="p1">
<inner/>
</outer>
<outer/>
</section>
<section id="2">
<outer>
<inner/>
</outer>
</section>
<section id="3">
<outer>
<inner/>
<inner/>
<inner/>
</outer>
</section>
</rootnode>
Комментарии:
1. Невозможно объединить два входных файла перед обработкой с помощью xslt? Может быть, это будет проще.
2. После конкатенации вы можете применить группировку и фильтрацию по-мюнхенски. www.jenitennison.com/xslt/grouping/muenchian.html
3. При беглом взгляде оба выглядят как одна и та же структура, причем первая практически не содержит данных. Почему бы просто не преобразовать second для выравнивания по первому?