簡體   English   中英

如何使用xslt將xml節點與某些條件結合在一起?

[英]how do I combine xml nodes with certain conditions using xslt?

我有兩個要合並的XML文檔。

forSale.xml:

<forSale>
<game>
    <cover>me3_cover.jpg</cover>
    <title>Mass Effect 3</title>
    <publisher>Electronic Arts</publisher>
    <developer>BioWare</developer>
    <genre>Role-Playing</genre>
    <releaseDate>
        <yyyy>2012</yyyy>
        <mm>03</mm>
        <dd>06</dd>
    </releaseDate>
    <esrbRating>M</esrbRating>
    <platforms>
        <platform>X360</platform>
        <platform>PC</platform>
        <platform>PS3</platform>
        <platform>WIIU</platform>
    </platforms>
</game>
<!--more games-->
</forSale>

reviews.xml:

<reviews>
<game>
    <title>Mass Effect 3</title>
    <review>
        <critic>Kevin VanOrd</critic>
        <synopsis>
            <![CDATA[some data]]>
        </synopsis>
        <pros>
            <pro><![CDATA[some data]]></pro>
            <pro><![CDATA[some data]]></pro>
            <pro><![CDATA[some data]]></pro>
            <pro><![CDATA[some data]]></pro>
            <pro><![CDATA[some data]]></pro>
        </pros>
        <cons>
            <con><![CDATA[some data]]></con>
            <con><![CDATA[some data]]></con>
        </cons>
        <content>
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
            <p />
            <img url="me3_img1.jpg"><![CDATA[some data]]></img>
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
            <p />
            <img url="me3_img2.jpg"><![CDATA[some data]]></img>
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
            <p />
            <img url="me3_img3.jpg"><![CDATA[some data]]></img>
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
            <p />
            <img url="me3_img4.jpg"><![CDATA[some data]]></img>
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
            <p />
            <img url="me3_img5.jpg"><![CDATA[some data]]></img>
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
            <p />
            <img url="me3_img6.jpg"><![CDATA[some data]]></img>
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
            <p />
            <img url="me3_img7.jpg"><![CDATA[some data]]></img>
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
            <p />
            <img url="me3_img8.jpg"><![CDATA[some data]]></img>
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
        </content>
    </review>
</game>
<!--more games-->
</reviews>

然后我希望輸出看起來像這樣:

<forSale>
<game>
    <cover>me3_cover.jpg</cover>
    <title>Mass Effect 3</title>
    <publisher>Electronic Arts</publisher>
    <developer>BioWare</developer>
    <genre>Role-Playing</genre>
    <releaseDate>
        <yyyy>2012</yyyy>
        <mm>03</mm>
        <dd>06</dd>
    </releaseDate>
    <esrbRating>M</esrbRating>
    <platforms>
        <platform>X360</platform>
        <platform>PC</platform>
        <platform>PS3</platform>
        <platform>WIIU</platform>
    </platforms>
    <review>
        <critic>Kevin VanOrd</critic>
        <synopsis>
            <![CDATA[some data]]>
        </synopsis>
        <pros>
            <pro><![CDATA[some data]]></pro>
            <pro><![CDATA[some data]]></pro>
            <pro><![CDATA[some data]]></pro>
            <pro><![CDATA[some data]]></pro>
            <pro><![CDATA[some data]]></pro>
        </pros>
        <cons>
            <con><![CDATA[some data]]></con>
            <con><![CDATA[some data]]></con>
        </cons>
        <content>
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
            <p />
            <img url="me3_img1.jpg"><![CDATA[some data]]></img>
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
            <p />
            <img url="me3_img2.jpg"><![CDATA[some data]]></img>
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
            <p />
            <img url="me3_img3.jpg"><![CDATA[some data]]></img>
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
            <p />
            <img url="me3_img4.jpg"><![CDATA[some data]]></img>
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
            <p />
            <img url="me3_img5.jpg"><![CDATA[some data]]></img>
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
            <p />
            <img url="me3_img6.jpg"><![CDATA[some data]]></img>
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
            <p />
            <img url="me3_img7.jpg"><![CDATA[some data]]></img>
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
            <p />
            <img url="me3_img8.jpg"><![CDATA[some data]]></img>
            <![CDATA[some data]]>
            <p />
            <![CDATA[some data]]>
        </content>
    </review>
</game>
<!--more games-->
</forSale>

我遇到的問題是,首先說當<title>標簽中reviews.xmlforSale.xml匹配,則審查必須添加其他不。 我必須使用xslt來執行此操作,到目前為止,我的代碼如下:

<forSale>
<xsl:for-each select="document('forSale.xml')/forSale/game">
    <game>
        <xsl:copy-of select="cover" />
        <xsl:copy-of select="title" />
        <xsl:variable name="title" select="title" />
        <xsl:copy-of select="publisher" />
        <xsl:copy-of select="developer" />
        <xsl:copy-of select="genre" />
        <xsl:copy-of select="releaseDate" />
        <xsl:copy-of select="esrbRating" />
        <xsl:copy-of select="platforms"/>
            <xsl:template match="document('reviews.xml')/reviews/game">
            <xsl:choose>
                <xsl:when test="./title = $title">
                    <xsl:copy>
                        <xsl:apply-templates select="./review" />
                    </xsl:copy>
                </xsl:when>
            </xsl:choose>
        </xsl:template>
    </game>

</xsl:for-each>
</forSale>

其次,我不知道如何完全復制<![CDATA[some data]]>

任何幫助,將不勝感激! 謝謝!

基本上,XSLT數據模型不會區分純文本節點和CDATA部分,因此,您輸入的內容是否具有<foo>some data</foo><foo><![CDATA[some data]]></foo>在XSLT處理器使用的輸入樹中建模。 因此,您不能確保按原樣復制此類元素。 但是,您可以使用以下命令指示XSLT處理器將某些結果元素的內容輸出為CDATA節:

<xsl:output cdata-section-elements="foo bar"/>

這樣可以確保XSLT轉換的序列化結果樹使用<foo><![CDATA[some data]]></foo><bar><![CDATA[a & b]]></bar> 但是,這將對那些名稱的所有元素發生,不僅對於那些從具有CDATA節內容的輸入中復制的元素而言。

問題第一部分的答案是:您可以像處理第一篇文檔一樣使用相同的思想來訪問第二篇文檔:

                <xsl:for-each select="document('reviews.xml')/reviews/game[title = $title]">
                    <xsl:copy>
                        <xsl:apply-templates select="review" />
                    </xsl:copy>
                </xsl:for-each>

更新:生成CDATA。

我不知道是否以及如何在輸入中測試CDATA。 但是您可以測試是否有可以轉義的字符,但是您不喜歡這樣做,可以使用CDATA。 嘗試這樣的事情:

<xsl:template match="text()">
    <xsl:choose>
        <xsl:when test="contains(.,'&lt;')">
            <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
            <xsl:value-of disable-output-escaping="yes" select="."/>
            <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of  select="."/>
        </xsl:otherwise>
    </xsl:choose>   
</xsl:template>

您問題的完整解決方案如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:fo="http://www.w3.org/1999/XSL/Format">
  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>
  <xsl:template match="/">
    <forSale>
      <xsl:for-each select="document('Untitled1.xml')/forSale/game">
        <game>
          <xsl:copy-of select="cover"/>
          <xsl:copy-of select="title"/>
          <xsl:variable name="title" select="title"/>
          <xsl:copy-of select="publisher"/>
          <xsl:copy-of select="developer"/>
          <xsl:copy-of select="genre"/>
          <xsl:copy-of select="releaseDate"/>
          <xsl:copy-of select="esrbRating"/>
          <xsl:copy-of select="platforms"/>
          <xsl:for-each select="document('Untitled2.xml')/reviews/game">
            <xsl:choose>
              <xsl:when test="./title = $title">
                <review>
                  <xsl:call-template name="checkChild">
                    <xsl:with-param name="self" select="self::node()/review"/>
                  </xsl:call-template>
                </review>
              </xsl:when>
            </xsl:choose>
          </xsl:for-each>
        </game>
      </xsl:for-each>
    </forSale>
  </xsl:template>

  <xsl:template name="checkChild">
    <xsl:param name="self"/>
    <xsl:for-each select="$self/child::node()">
      <xsl:message>
        <xsl:value-of select="name()"/>
      </xsl:message>
      <xsl:choose>
        <xsl:when test="self::node()/name() = 'pros'">
          <pros>
            <xsl:for-each select="pro">
              <pro>
                <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
                <xsl:value-of select="."/>
                <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
              </pro>
            </xsl:for-each>
          </pros>

        </xsl:when>
        <xsl:when test="self::node()/name() = 'synopsis'">
          <xsl:copy>
            <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
            <xsl:value-of select="."/>
            <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
          </xsl:copy>
        </xsl:when>
        <xsl:when test="self::node()/name() = 'cons'">
          <cons>
            <xsl:for-each select="con">
              <con>
                <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
                <xsl:value-of select="."/>
                <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
              </con>
            </xsl:for-each>
          </cons>
        </xsl:when>
        <xsl:when test="self::node()/name() = 'content'">
          <content>

            <xsl:for-each select="child::node()">
              <xsl:choose>
                <xsl:when test="self::text()">
                  <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
                  <xsl:value-of select="."/>
                  <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
                </xsl:when>
                <xsl:when test="self::node()/name()= 'img'">
                  <xsl:element name="{name()}">
                    <xsl:if test="@url">
                      <xsl:attribute name="url">
                        <xsl:value-of select="@url"/>
                      </xsl:attribute>
                    </xsl:if>
                    <xsl:text disable-output-escaping="yes">&lt;![CDATA[</xsl:text>
                    <xsl:value-of select="."/>
                    <xsl:text disable-output-escaping="yes">]]&gt;</xsl:text>
                  </xsl:element>
                </xsl:when>
                <xsl:otherwise>
                  <xsl:copy>
                    <xsl:copy-of select="node()"/>
                  </xsl:copy>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:for-each>
          </content>
        </xsl:when>
        <xsl:otherwise>
          <xsl:copy>
            <xsl:copy-of select="node()"/>
          </xsl:copy>
        </xsl:otherwise>
      </xsl:choose>

    </xsl:for-each>
  </xsl:template>


</xsl:stylesheet>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM