/ / xpath opcjonalny atrybut z atrybutami wewnętrznymi - xml, xslt, xpath

xpath opcjonalny atrybut z wewnętrznymi atrybutami - xml, xslt, xpath

Mam ten XML z zagnieżdżonym elementem, który jest opcjonalny i muszę utworzyć plik csv z atrybutami z hierarchii, nawet jeśli opcjonalny atrybut nie jest obecny.

oto plik danych xml:

    <dataroot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://mycomp.com/test/xml/model">
<ELEMENTS>
<COUNTRY cod_cnt="030">
<AS cod_as="030308">
<CONTRACT num_CONTRACT="8715167"/>
<CONTRACT num_CONTRACT="8715224"/>
</AS>
<AS cod_as="030309"/>
</COUNTRY>
</ELEMENTS>
</dataroot>

Potrzebuję elementów, które mają tag AS, nawet jeśli ma KONTRAKT, czy nie. Napisałem coś takiego, ale utknąłem:

<xsl:for-each select="/doc:dataroot/doc:ELEMENTS/doc:COUNTRY/doc:AS/doc:CONTRACT">
<xsl:value-of select="../../@cod_cnt"/>@<xsl:value-of select="../@cod_as"/>
@<xsl:value-of select="@num_CONTRACT"/>@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@D<xsl:text> </xsl:text>
</xsl:for-each>

Wiem, że tęsknię za czymś w rodzaju związku, ale nie mogę iść dalej.

Spodziewam się tego wyjścia:

030@030308@8715167@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@D
030@030308@8715224@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@D
030@030309@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@D

Zauważ, że pierwsze dwa wiersze to wynik, który otrzymałem z dołączonymi plikami xls, a trzeci wiersz jest napisany odręcznie, aby pokazać wyniki, których się spodziewam.

Odpowiedzi:

0 dla odpowiedzi № 1

Jeśli chcesz cię zatrzymać for-each struktura, poniższe stwierdzenia powinny działać dla Ciebie. Najpierw musisz wykonać iterację doc:AS potem dalej doc:CONTRACT Jeśli w ogóle.

 <xsl:for-each select="/doc:dataroot/doc:ELEMENTS/doc:COUNTRY/doc:AS">
<xsl:value-of select="../@cod_cnt"/><xsl:text>@</xsl:text><xsl:value-of select="@cod_as"/>
<xsl:for-each select="doc:CONTRACT>
<xsl:text>@</xsl:text><xsl:value-of select="@num_CONTRACT"/>
</xsl:for-each>
<xsl:text>@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@D</xsl:text>
</xsl:for-each>

Ale osobiście wolę używać dopasowywania szablonów, a to da coś takiego w twoim przypadku (nie testowane):

<xsl:template match="/">
<!-- Select the <doc:AS> if they are your "rows" in the csv output -->
<xsl:apply-template match="/doc:dataroot/doc:ELEMENTS/doc:COUNTRY/doc:AS"/>
</xsl:template>

<xsl:template match="doc:AS">
<!-- Do the job for the doc:AS -->
<xsl:value-of select="../@cod_cnt"/><xsl:text>@</xsl:text><xsl:value-of select="@cod_as"/>
<!-- Call template for doc:Contract if any -->
<xsl:apply-templates select="doc:Contract"/>
<!-- Then add the end of your row -->
<xsl:text>@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@0@D</xsl:text>
</xsl:template>

<xsl:template match="doc:CONTRACT">
<!-- Do the job for doc:CONTRACT-->
<xsl:text>@</xsl:text><xsl:value-of select="@num_CONTRACT"/>
</xsl:template>