1

次のためのより良い解決策を持つことは可能ですか?

入力xml

<product>

<text>
<languageId>en-us</languageId>
<description>some text en us</description>
</text>

<text>
<languageId>en-gb</languageId>
<description>some text en gb</description>
</text>

<text>
<languageId>en-us</languageId>
</text>

<product>

出力xml

<specifications>some text en us</specifications>

したがって、languageId = en-usの説明があり、テキストが存在する場合、このテキストは出力xmlに配置されます。それ以外の場合、要素は属性値xsi:nil=trueを受け取ります。

xsltバージョンは1.0である必要があります

XSLT

 <ns0:specifications>

          <!-- First loop, check if en-us is present, if so, check if there is a text! -->
          <!-- If the 2 requirements are met, then this Txt element is used -->
          <xsl:for-each select="s0:text">
            <xsl:if test="translate(s0:LanguageId/text(),$smallcase,$uppercase)=translate('en-us',$smallcase,$uppercase)">
              <xsl:if test="s0:Txt!=''">
                <xsl:value-of select="s0:Txt/text()" />
              </xsl:if>
            </xsl:if>
          </xsl:for-each>

        <!-- Second loop, checks are the same. This loop is needed because xsl variables are immutable. If there is a better solution, just change the code!! -->
        <!-- If the 2 requirements are met, then the variable is marked as true, else it's empty -->
        <xsl:variable name="isEnUsPresent">
          <xsl:for-each select="s0:text">
            <xsl:if test="translate(s0:LanguageId/text(),$smallcase,$uppercase)=translate('en-us',$smallcase,$uppercase)">
              <xsl:if test="s0:Txt!=''">
                <xsl:value-of select="1" />
              </xsl:if>
            </xsl:if>
          </xsl:for-each>
        </xsl:variable>

        <!-- if the variable is empty, set the attribute value xsi:nil=true like below -->
        <xsl:choose>
          <xsl:when test="$isEnUsPresent=''">
            <xsl:attribute name="xsi:nil">
              <xsl:value-of select="'true'" />
            </xsl:attribute>
          </xsl:when>
        </xsl:choose>

</ns0:specifications> 

よろしく

4

1 に答える 1

1

これと同じくらい簡単です:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 exclude-result-prefixes="xsi">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="/">
     <specifications>
      <xsl:apply-templates select="*"/>
     </specifications>
 </xsl:template>    

 <xsl:template match="text[languageId='en-us']/description">
  <xsl:value-of select="."/>
 </xsl:template>

 <xsl:template match="/*[not(text[languageId='en-us']/description)]">
  <xsl:attribute name="xsi:nil">true</xsl:attribute>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

この変換が提供されたXMLドキュメントに適用される場合:

<product>
    <text>
        <languageId>en-us</languageId>
        <description>some text en us</description>
    </text>
    <text>
        <languageId>en-gb</languageId>
        <description>some text en gb</description>
    </text>
    <text>
        <languageId>en-us</languageId>
    </text>
</product>

必要な正しい結果が生成されます。

<specifications>some text en us</specifications>

同じ変換がこのXMLドキュメントに適用される場合

<product>
    <text>
        <languageId>en-us-XXX</languageId>
        <description>some text en us</description>
    </text>
    <text>
        <languageId>en-gb</languageId>
        <description>some text en gb</description>
    </text>
    <text>
        <languageId>en-us</languageId>
    </text>
</product>

ここでも、必要な正しい結果が生成されます。

<specifications xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
于 2012-11-19T18:06:03.543 に答える