我的任务是创建XSLT转换。 在过程语言中,解决方案看起来像这样:
foreach( Book book in set)
{
int importanceIndicator = 0;
foreach( Page page in book )
{
if(page.name == "important_page")
{
importanceIndicator = 1;
break;
}
}
book.newField.importanceIndicator = importanceIndicator;
}
如何在XSLT中解决这个问题(与程序语言有很大不同)?
示例XML文件:
输入:
<set>
<book>
<page name="important_page"></page>
<page name="first_page"></page>
<page name="important_page"></page>
<page name="second_page"></page>
<page name="important_page"></page>
</book>
<book>
<page name="another_page"></page>
<page name="first_page"></page>
<page name="3_page"></page>
<page name="second_page"></page>
<page name="another_page"></page>
</book>
<book>
<page name="important_page"></page>
<page name="first_page"></page>
<page name="important_page"></page>
<page name="second_page"></page>
<page name="another_page"></page>
</book>
</set>
输出:
<set>
<book>
<newField importance_indicator="1"></newField>
</book>
<book>
<newField importance_indicator="0"></newField>
</book>
<book>
<newField importance_indicator="1"></newField>
</book>
</set>
答案 0 :(得分:2)
在XSLT中,您不需要循环来完成此任务。处理book节点时,可以检查其子节点的内容。
<xsl:template match="book">
<newfield>
<xsl:choose>
<xsl:when test="page/@name='important page'">
<xsl:attribute name="importance_indicator" select="1">
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="importance_indicator" select="0">
</xsl:otherwise>
答案 1 :(得分:1)
首先从identity template开始(在这种情况下只会复制set
节点)
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
然后,在转换book
元素时,您需要一个与book
匹配的新模板,您可以在其中复制book
元素并添加newField
元素< / p>
<xsl:template match="book">
<xsl:copy>
<newField>
<!-- Add code for attribute -->
</newField>
</xsl:copy>
</xsl:template>
要创建属性,您可以xsl:attribute
使用包含条件的xsl:choose
进行检查
<xsl:attribute name="importance_indicator">
<xsl:choose>
<xsl:when test="page[@name='important_page']">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
试试这个XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="book">
<xsl:copy>
<newField>
<xsl:attribute name="importance_indicator">
<xsl:choose>
<xsl:when test="page[@name='important_page']">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</newField>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
请注意,匹配“book”的模板可以通过使用Attribute Value Templates(由{ }
符号表示来简化,这些符号会导致内部表达式被评估,而不是按字面输出)
<xsl:template match="book">
<xsl:copy>
<newField importance_indicator="{number(boolean(page[@name='important_page']))}"/>
</xsl:copy>
</xsl:template>
如果page[@name='important_page'])
是“important_page”,page
将会选择boolean()
。 <compatible-screens>
<!-- all small size screens -->
<screen android:screenSize="small" android:screenDensity="ldpi" />
<screen android:screenSize="small" android:screenDensity="mdpi" />
<screen android:screenSize="small" android:screenDensity="hdpi" />
<screen android:screenSize="small" android:screenDensity="xhdpi" />
<screen android:screenSize="small" android:screenDensity="xxhdpi" />
<screen android:screenSize="small" android:screenDensity="xxxhdpi" />
<!-- all normal size screens -->
<screen android:screenSize="normal" android:screenDensity="ldpi" />
<screen android:screenSize="normal" android:screenDensity="mdpi" />
<screen android:screenSize="normal" android:screenDensity="hdpi" />
<screen android:screenSize="normal" android:screenDensity="xhdpi" />
<screen android:screenSize="normal" android:screenDensity="xxhdpi" />
<screen android:screenSize="normal" android:screenDensity="xxxhdpi" />
</compatible-screens>
将返回true或false,具体取决于该页面是否存在,然后number将“true”转换为“1”或“false”为“0”。
答案 2 :(得分:0)
我找到了答案,可以这样做:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<set>
<xsl:for-each select="set">
<xsl:for-each select="book">
<book>
<xsl:variable name="importanceIndicatorTmp">
<xsl:choose>
<xsl:when test= "page/@name = 'important_page'">1</xsl:when>
<xsl:otherwise>0</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<newField importanceIndicator="{$importanceIndicatorTmp}"></newField>
</book>
</xsl:for-each>
</xsl:for-each>
</set>
</xsl:template>
</xsl:stylesheet>