Xml 组合XSLT中2个列表中的元素
假设我有这样的XML(并且假设我无法更改此XML的格式):Xml 组合XSLT中2个列表中的元素,xml,xslt,Xml,Xslt,假设我有这样的XML(并且假设我无法更改此XML的格式): 霍布诺布斯 1.49 消化液 89 6克 太多了 3克 5克 我想使用XSLT将其转化为如下内容: <biscuit> <name>Hobnobs</name> <price>1.49</price> <fat>6 grams</fat> <sugar>lots</sugar> <
霍布诺布斯
1.49
消化液
89
6克
太多了
3克
5克
我想使用XSLT将其转化为如下内容:
<biscuit>
<name>Hobnobs</name>
<price>1.49</price>
<fat>6 grams</fat>
<sugar>lots</sugar>
</biscuit>
霍布诺布斯
1.49
6克
太多了
我如何在XSLT中执行类似的操作?我可以循环浏览第一个饼干列表(名称和价格)并从第二个列表(营养价值)中提取元素吗
我对XSL不太了解,所以欢迎提供任何建议
干杯
JD.第二部分可以使用XPath。在第一个列表上执行循环,一旦找到名称,就使用XPath查询第二个列表中所需的内容。您可以在第二部分使用XPath。在第一个列表上执行循环,一旦获得名称,就使用XPath查询第二个列表中所需的内容。此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:key name="bisquit-info" match="/root/biscuitInfo" use="@name"/>
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates select="biscuit/name"/>
</xsl:copy>
</xsl:template>
<xsl:template match="name">
<bisquit>
<xsl:copy-of select="."/>
<xsl:copy-of select="following-sibling::price[1]"/>
<xsl:copy-of select="key('bisquit-info', .)/nutritionalValue/*"/>
</bisquit>
</xsl:template>
</xsl:stylesheet>
使用这样的XML输入(只是为了良好的格式添加了根节点)
霍布诺布斯
1.49
消化液
89
6克
太多了
3克
5克
将提供以下结果:
<root>
<bisquit>
<name>Hobnobs</name>
<price>1.49</price>
<fat>6 grams</fat>
<sugar>lots</sugar>
</bisquit>
<bisquit>
<name>Digestives</name>
<price>89.00</price>
<fat>3 grams</fat>
<sugar>5 grams</sugar>
</bisquit>
</root>
霍布诺布斯
1.49
6克
太多了
消化液
89
3克
5克
设计并不理想,但这会起作用。我使用键,假设输入树可以很大。此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:key name="bisquit-info" match="/root/biscuitInfo" use="@name"/>
<xsl:template match="root">
<xsl:copy>
<xsl:apply-templates select="biscuit/name"/>
</xsl:copy>
</xsl:template>
<xsl:template match="name">
<bisquit>
<xsl:copy-of select="."/>
<xsl:copy-of select="following-sibling::price[1]"/>
<xsl:copy-of select="key('bisquit-info', .)/nutritionalValue/*"/>
</bisquit>
</xsl:template>
</xsl:stylesheet>
使用这样的XML输入(只是为了良好的格式添加了根节点)
霍布诺布斯
1.49
消化液
89
6克
太多了
3克
5克
将提供以下结果:
<root>
<bisquit>
<name>Hobnobs</name>
<price>1.49</price>
<fat>6 grams</fat>
<sugar>lots</sugar>
</bisquit>
<bisquit>
<name>Digestives</name>
<price>89.00</price>
<fat>3 grams</fat>
<sugar>5 grams</sugar>
</bisquit>
</root>
霍布诺布斯
1.49
6克
太多了
消化液
89
3克
5克
设计并不理想,但这会起作用。我使用键,假设输入树可以很大。两个示例。此样式表使用clasic完全递归:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kNutChildByBisName" match="nutritionalValue/*"
use="../../@name"/>
<xsl:key name="kElemByPrecedingName" match="biscuit/*[not(self::name)]"
use="preceding-sibling::name[1]"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="name" mode="group">
<bisquit>
<xsl:apply-templates select=".|key('kNutChildByBisName',.)|
key('kElemByPrecedingName',.)"/>
</bisquit>
</xsl:template>
<xsl:template match="biscuit">
<xsl:apply-templates mode="group"/>
</xsl:template>
<xsl:template match="biscuitInfo"/>
<xsl:template match="node()" mode="group"/>
</xsl:stylesheet>
此样式表使用细粒度遍历:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:key name="kNutByBisName" match="nutritionalValue"
use="../@name"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()[1]|@*"/>
</xsl:copy>
<xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="biscuitInfo"/>
<xsl:template match="biscuit">
<xsl:apply-templates select="node()[1]|following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="name[1]" name="group">
<bisquit>
<xsl:call-template name="identity"/>
<xsl:apply-templates select="key('kNutByBisName',.)/node()[1]"/>
</bisquit>
<xsl:apply-templates select="following-sibling::name[1]" mode="group"/>
</xsl:template>
<xsl:template match="name"/>
<xsl:template match="name" mode="group">
<xsl:call-template name="group"/>
</xsl:template>
</xsl:stylesheet>
<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="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="biscuit/name">
<biscuit>
<xsl:call-template name="identity"/>
<xsl:apply-templates select=
"following-sibling::price[1]
|
../../biscuitInfo[@name = current()]/*"/>
</biscuit>
</xsl:template>
<xsl:template match="biscuit">
<xsl:apply-templates select="name"/>
</xsl:template>
<xsl:template match="nutritionalValue">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="biscuitInfo"/>
</xsl:stylesheet>
通过此输入:
<root>
<biscuit>
<name>Hobnobs</name>
<price>1.49</price>
<name>Digestives</name>
<price>89.00</price>
</biscuit>
<biscuitInfo name="Hobnobs">
<nutritionalValue>
<fat>6 grams</fat>
<sugar>lots</sugar>
</nutritionalValue>
</biscuitInfo>
<biscuitInfo name="Digestives">
<nutritionalValue>
<fat>3 grams</fat>
<sugar>5 grams</sugar>
</nutritionalValue>
</biscuitInfo>
</root>
霍布诺布斯
1.49
消化液
89
6克
太多了
3克
5克
两种输出:
<root>
<bisquit>
<name>Hobnobs</name>
<price>1.49</price>
<fat>6 grams</fat>
<sugar>lots</sugar>
</bisquit>
<bisquit>
<name>Digestives</name>
<price>89.00</price>
<fat>3 grams</fat>
<sugar>5 grams</sugar>
</bisquit>
</root>
霍布诺布斯
1.49
6克
太多了
消化液
89
3克
5克
注意:您正在执行两项任务:分组和交叉引用
编辑:在组中只有
名称
的情况下进行更好的细粒度遍历。两个示例。此样式表使用clasic完全递归:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kNutChildByBisName" match="nutritionalValue/*"
use="../../@name"/>
<xsl:key name="kElemByPrecedingName" match="biscuit/*[not(self::name)]"
use="preceding-sibling::name[1]"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="name" mode="group">
<bisquit>
<xsl:apply-templates select=".|key('kNutChildByBisName',.)|
key('kElemByPrecedingName',.)"/>
</bisquit>
</xsl:template>
<xsl:template match="biscuit">
<xsl:apply-templates mode="group"/>
</xsl:template>
<xsl:template match="biscuitInfo"/>
<xsl:template match="node()" mode="group"/>
</xsl:stylesheet>
此样式表使用细粒度遍历:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:key name="kNutByBisName" match="nutritionalValue"
use="../@name"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()[1]|@*"/>
</xsl:copy>
<xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="biscuitInfo"/>
<xsl:template match="biscuit">
<xsl:apply-templates select="node()[1]|following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="name[1]" name="group">
<bisquit>
<xsl:call-template name="identity"/>
<xsl:apply-templates select="key('kNutByBisName',.)/node()[1]"/>
</bisquit>
<xsl:apply-templates select="following-sibling::name[1]" mode="group"/>
</xsl:template>
<xsl:template match="name"/>
<xsl:template match="name" mode="group">
<xsl:call-template name="group"/>
</xsl:template>
</xsl:stylesheet>
<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="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="biscuit/name">
<biscuit>
<xsl:call-template name="identity"/>
<xsl:apply-templates select=
"following-sibling::price[1]
|
../../biscuitInfo[@name = current()]/*"/>
</biscuit>
</xsl:template>
<xsl:template match="biscuit">
<xsl:apply-templates select="name"/>
</xsl:template>
<xsl:template match="nutritionalValue">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="biscuitInfo"/>
</xsl:stylesheet>
通过此输入:
<root>
<biscuit>
<name>Hobnobs</name>
<price>1.49</price>
<name>Digestives</name>
<price>89.00</price>
</biscuit>
<biscuitInfo name="Hobnobs">
<nutritionalValue>
<fat>6 grams</fat>
<sugar>lots</sugar>
</nutritionalValue>
</biscuitInfo>
<biscuitInfo name="Digestives">
<nutritionalValue>
<fat>3 grams</fat>
<sugar>5 grams</sugar>
</nutritionalValue>
</biscuitInfo>
</root>
霍布诺布斯
1.49
消化液
89
6克
太多了
3克
5克
两种输出:
<root>
<bisquit>
<name>Hobnobs</name>
<price>1.49</price>
<fat>6 grams</fat>
<sugar>lots</sugar>
</bisquit>
<bisquit>
<name>Digestives</name>
<price>89.00</price>
<fat>3 grams</fat>
<sugar>5 grams</sugar>
</bisquit>
</root>
霍布诺布斯
1.49
6克
太多了
消化液
89
3克
5克
注意:您正在执行两项任务:分组和交叉引用
编辑:在组中只有
名称
的情况下,进行更好的细粒度遍历。传统的标识规则被几个模板覆盖。无键,无精细纹理遍历:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:key name="kNutByBisName" match="nutritionalValue"
use="../@name"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()[1]|@*"/>
</xsl:copy>
<xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="biscuitInfo"/>
<xsl:template match="biscuit">
<xsl:apply-templates select="node()[1]|following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="name[1]" name="group">
<bisquit>
<xsl:call-template name="identity"/>
<xsl:apply-templates select="key('kNutByBisName',.)/node()[1]"/>
</bisquit>
<xsl:apply-templates select="following-sibling::name[1]" mode="group"/>
</xsl:template>
<xsl:template match="name"/>
<xsl:template match="name" mode="group">
<xsl:call-template name="group"/>
</xsl:template>
</xsl:stylesheet>
<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="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="biscuit/name">
<biscuit>
<xsl:call-template name="identity"/>
<xsl:apply-templates select=
"following-sibling::price[1]
|
../../biscuitInfo[@name = current()]/*"/>
</biscuit>
</xsl:template>
<xsl:template match="biscuit">
<xsl:apply-templates select="name"/>
</xsl:template>
<xsl:template match="nutritionalValue">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="biscuitInfo"/>
</xsl:stylesheet>
应用于此源XML时(基本上是提供的,但包装在单个顶部元素中):
霍布诺布斯
1.49
消化液
89
6克
太多了
3克
5克
生成所需的正确结果:
<product>
<biscuit>
<name>Hobnobs</name>
<price>1.49</price>
<fat>6 grams</fat>
<sugar>lots</sugar>
</biscuit>
<biscuit>
<name>Digestives</name>
<price>89.00</price>
<fat>3 grams</fat>
<sugar>5 grams</sugar>
</biscuit>
</product>
霍布诺布斯
1.49
6克
太多了
消化液
89
3克
5克
注意事项:
<product>
<biscuit>
<name>Hobnobs</name>
<price>1.49</price>
<fat>6 grams</fat>
<sugar>lots</sugar>
</biscuit>
<biscuit>
<name>Digestives</name>
<price>89.00</price>
<fat>3 grams</fat>
<sugar>5 grams</sugar>
</biscuit>
</product>
而不是
允许并行执行,这在不久的将来可能变得越来越重要传统标识规则被几个模板覆盖。无键,无精细纹理遍历:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:key name="kNutByBisName" match="nutritionalValue"
use="../@name"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()[1]|@*"/>
</xsl:copy>
<xsl:apply-templates select="following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="biscuitInfo"/>
<xsl:template match="biscuit">
<xsl:apply-templates select="node()[1]|following-sibling::node()[1]"/>
</xsl:template>
<xsl:template match="name[1]" name="group">
<bisquit>
<xsl:call-template name="identity"/>
<xsl:apply-templates select="key('kNutByBisName',.)/node()[1]"/>
</bisquit>
<xsl:apply-templates select="following-sibling::name[1]" mode="group"/>
</xsl:template>
<xsl:template match="name"/>
<xsl:template match="name" mode="group">
<xsl:call-template name="group"/>
</xsl:template>
</xsl:stylesheet>
<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="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="biscuit/name">
<biscuit>
<xsl:call-template name="identity"/>
<xsl:apply-templates select=
"following-sibling::price[1]
|
../../biscuitInfo[@name = current()]/*"/>
</biscuit>
</xsl:template>
<xsl:template match="biscuit">
<xsl:apply-templates select="name"/>
</xsl:template>
<xsl:template match="nutritionalValue">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="biscuitInfo"/>
</xsl:stylesheet>
应用于此源XML时(基本上是提供的,但包装在单个顶部元素中):
霍布诺布斯
1.49
消化液
89