用于从非线性XML结构中提取元素的XSLT
我有一个XML架构,其XML格式不规则/未格式化。该结构看起来像这 -用于从非线性XML结构中提取元素的XSLT
<Host>
<element1>type0</element1>
<element2>Fruits</element2>
....
<elementn>Price0</elementn>
<Menu>
<NodeA>
<element1>type1</element1>
<element2>Fruits</element2>
....
<elementn>Price1</elementn>
<Menu>
<NodeB>
<element1>type2</element1>
<element2>Fruits</element2>
....
<elementn>Price2</elementn>
<Menu>
<NodeC>
<element1>type3</element1>
<element2>Fruits</element2>
....
<elementn>Price3</elementn>
<Menu>
<NodeD>
<Element1>type4</element1>
<Element2>Vegetables</Element2>
....
<Elementn>Price4</elementn>
</NodeD>
</Menu>
</NodeC>
</Menu>
</NodeB>
</Menu>
</NodeA>
<NodeE>
<element1>type5</element1>
<element2>Fruits</element2>
....
<elementn>Price5</elementn>
<Menu>
<NodeF>
<element1>type6</element1>
<element2>Vegetables</element2>
....
<elementn>Price6</elementn>
</NodeF>
</Menu>
</NodeE>
</Menu>
</Host>
现在我预期的XML如下 -
a)如果在所有节点<element2>
==水果,我需要的XML模式如下。我可以包含或排除右下主机下面的n个元素 -
`<element1>type0</element>
<element2>Fruits</element2>
....
<elementn>Price0</elementn>`
。预计结果 -
<Host>
<NodeA>
<element1>type1</element1>
<element2>Fruits</element2>
....
<elementn>Price1</elementn>
</NodeA>
<NodeB>
<element1>type2</element1>
<element2>Fruits</element2>
....
<elementn>Price2</elementn>
</NodeB>
<NodeC>
<element1>type3</element1>
<element2>Fruits</element2>
....
<elementn>Price3</elementn>
</NodeC>
<NodeE>
<element1>type5</element1>
<element2>Fruits</element2>
....
<elementn>Price5</elementn>
</NodeE>
</Host>
二)如果在所有节点<element2>
==蔬菜,我需要的XML模式如下
注:<element2>
==蔬菜总是在架构中的最后一个节点
<Host>
<NodeD>
<element1>type4</element1>
<element2>Vegetables</element2>
....
<elementn>Price4</elementn>
</NodeD>
<NodeF>
<element1>type6</element1>
<element2>Vegetables</element2>
....
<elementn>Price6</elementn>
</NodeF>
</Host>
通过XSLT获取上述XML格式的任何帮助都将非常有帮助。
如果您需要2个单独的文档,您实际上不需要2个XSLT。您可以使用一个XSLT但参数
<xsl:param name="element2" select="'Fruits'" />
(以下'Fruits'
只是默认值,如果参数不通过调用应用程序指定)。
你会开始通过选择具有element2
等于参数(待办事项XML和XSLT是大小写敏感的节点,所以element2
是不一样在你的XML Element2
,但我以为这是一个错字你的XML)。
<xsl:apply-templates select="//*[element2=$element2]"/>
您还需要一个模板,以确保当一个节点匹配,它不会复制子节点...
<xsl:template match="*[element2]">
<xsl:copy>
<xsl:apply-templates select="*[not(*)]" />
</xsl:copy>
</xsl:template>
其他节点将由身份模板来处理。
试试这个XSLT ...
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:param name="element2" select="'Fruits'" />
<xsl:template match="/*">
<xsl:copy>
<xsl:apply-templates select="//*[element2=$element2]" mode="copy"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[element2]" mode="copy">
<xsl:copy>
<xsl:apply-templates select="*[not(*)]" mode="copy"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()" mode="copy">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="copy"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
请注意,如果你使用XSLT 2.0,你可以在一个呼叫建立多个文档,使用xsl:for-each-group
得到不同的群体,并xsl:result-document
创建一个文件每。
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/*">
<xsl:for-each-group select="//*[element2]" group-by="element2">
<xsl:result-document href="{current-grouping-key()}.xml" method="xml">
<Host>
<xsl:apply-templates select="current-group()" mode="copy" />
</Host>
</xsl:result-document>
</xsl:for-each-group>
</xsl:template>
<xsl:template match="*[element2]" mode="copy">
<xsl:copy>
<xsl:apply-templates select="*[not(*)]" mode="copy"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@*|node()" mode="copy">
<xsl:copy>
<xsl:apply-templates select="@*|node()" mode="copy" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
我试图第一XSLT和我看到错误 - “歧义规则匹配/根 匹配两者‘* [在element2]’上线的 12和‘/ *’上的第6行” –
我试图第二XSLT,我看到一个错误 - '模糊规则匹配/根 匹配 行14上的“* [element2]”和' –
第4行上的“/ *”我已经对我的答案进行了更正处理冲突的模板。 –
您的输入或输出都不是有效的XML,因此无法使用XML工具进行处理。此外,所有节点中的条件语句_“如果' == fruits',预期的XML将如下所示”_留下许多可能性,例如一些值为'fruits',一些为'vegetables'。这个问题还不清楚。 –
仍然无效的XML。例如''没有结束标签。 –
你的观点(a)指的是'所有节点中的水果'情况。你的观点(b)指的是“所有节点中的蔬菜”情况。但是你的XML既有水果也有蔬菜,所以(a)和(b)不适用。在XML既有水果又有蔬菜的情况下会发生什么?你想要生成多个XML文档吗?或者他们是否应该在蔬菜前以水果的形式出现在相同的输出中?谢谢。 –