[英]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.xml
和forSale.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(.,'<')">
<xsl:text disable-output-escaping="yes"><![CDATA[</xsl:text>
<xsl:value-of disable-output-escaping="yes" select="."/>
<xsl:text disable-output-escaping="yes">]]></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"><![CDATA[</xsl:text>
<xsl:value-of select="."/>
<xsl:text disable-output-escaping="yes">]]></xsl:text>
</pro>
</xsl:for-each>
</pros>
</xsl:when>
<xsl:when test="self::node()/name() = 'synopsis'">
<xsl:copy>
<xsl:text disable-output-escaping="yes"><![CDATA[</xsl:text>
<xsl:value-of select="."/>
<xsl:text disable-output-escaping="yes">]]></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"><![CDATA[</xsl:text>
<xsl:value-of select="."/>
<xsl:text disable-output-escaping="yes">]]></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"><![CDATA[</xsl:text>
<xsl:value-of select="."/>
<xsl:text disable-output-escaping="yes">]]></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"><![CDATA[</xsl:text>
<xsl:value-of select="."/>
<xsl:text disable-output-escaping="yes">]]></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.