有人可以建议我如何使用xslt实现以下目标吗?
这是xml输入:
<output>
<header>
<someId>ABC123</someId>
</header>
<results>
<product id="A">
<externalId>XYZ666</externalId>
<title>some title a</title>
</product>
<product id="B">
<externalId>ABC123</externalId>
<title>some title b</title>
</product>
<product id="C">
<externalId>666777</externalId>
<title>some title c</title>
</product>
</results>
</output>
我需要的是一个xslt,它只返回“product”,其中\ product \ externalId与\ header \ someId匹配,否则它匹配所有\ product元素。
任何建议都非常感谢。
答案 0 :(得分:1)
您应该使用<xsl:when test="condition">
..
对于您的XML,我提供了示例XSLT代码以有条件地选择节点。
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="results/product">
<xsl:choose>
<xsl:when test="externalId = /output/header/someId">
<!--Here goes the code-->
<something></something>
</xsl:when>
<xsl:otherwise>
<!--Other code -->
<somethingelse></somethingelse>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
上面的代码表现得像..
if ("externalId = /output/header/someId") then
<!--Here goes the code-->
<something></something>
else
<!--Other code -->
<somethingelse></somethingelse>
使用Indentity模板覆盖!
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="results/product[externalId = /output/header/someId]">
<!--Here goes the code-->
<something></something>
</xsl:template>
<xsl:template match="results/product[externalId != /output/header/someId]">
<!--Here goes the code-->
<somethingelse></somethingelse>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
就这么简单 - 没有变数,没有xsl:chose
,没有xsl:when
,没有xsl:otherwise
:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:copy-of select=
"/*[header/someId]/results/product[externalId=/*/header/someId]
|
/*[not(header/someId)]/results/product
"/>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档上应用此转换时:
<output>
<header>
<someId>ABC123</someId>
</header>
<results>
<product id="A">
<externalId>XYZ666</externalId>
<title>some title a</title>
</product>
<product id="B">
<externalId>ABC123</externalId>
<title>some title b</title>
</product>
<product id="C">
<externalId>666777</externalId>
<title>some title c</title>
</product>
</results>
</output>
产生了想要的正确结果:
<product id="B">
<externalId>ABC123</externalId>
<title>some title b</title>
</product>
对此XML文档应用相同的转换时:
<output>
<results>
<product id="A">
<externalId>XYZ666</externalId>
<title>some title a</title>
</product>
<product id="B">
<externalId>ABC123</externalId>
<title>some title b</title>
</product>
<product id="C">
<externalId>666777</externalId>
<title>some title c</title>
</product>
</results>
</output>
再次生成想要的正确结果:
<product id="A">
<externalId>XYZ666</externalId>
<title>some title a</title>
</product>
<product id="B">
<externalId>ABC123</externalId>
<title>some title b</title>
</product>
<product id="C">
<externalId>666777</externalId>
<title>some title c</title>
</product>
<强>解释强>:
当给定条件Exp1
为someCondition
时,我们使用通用方法选择一个节点集(通过表达式true()
)并选择另一个节点集(通过表达式) Exp2
}当相同条件为false()
时。
两个表达式为union-ed,每个表达式都可以在两个互斥条件下选择一个节点,因此,根据条件的值,只有一个表达式可以选择一个节点。
Exp1[someCondition] | Exp2[not(someCondition)]
答案 2 :(得分:0)
关于w3schools的教程是一个很好的起点!
尝试查看this页面!
答案 3 :(得分:0)
<xsl:key name="by-id" match="product" use="externalId"/>
<xsl:template match="/">
<xsl:variable name="ref" select="key('by-id', //header/someId)"/>
<xsl:choose>
<xsl:when test="$ref">
<xsl:copy-of select="$ref"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="//product"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
显示了如何使用密钥交叉引用节点。