我正在尝试重组xml。因此需要拆分产品。我已经在自己的帮助下完成了一些xslt,但是这些都是用于将XML拆分为多个XML的。但是,这似乎更具挑战性。我在努力从哪里开始。任何帮助都会很棒。我正在使用XSLT 2.0。
欢呼
输入XML
<div property="title">
{% if content.title %}
<h1>{{ content.title }}</h1>
{% endif %}
</div>
结果XML
<?xml version="1.0"?>
<Order_Root>
<Orders Number="12345">
<Info Name="John Doe" Reference="1/2/2019">
<LineItems>
<LineItem LineItemNumber="01" CustomerProductName="Test">
<LineItemPrice Price="0" Charge="0" />
<Products>
<Product ProductName="A" />
<Product ProductName="B" />
<Product ProductName="C" />
</Products>
</LineItem>
</LineItems>
</Info>
</Orders>
</Order_Root>
答案 0 :(得分:0)
我认为它可以作为将XSLT 3的snapshot
函数与第二种模式和隧道参数一起用于传递该LineItemPrice
的一个很好的例子:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="3.0">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:mode on-no-match="shallow-copy"/>
<xsl:mode name="price" on-no-match="shallow-copy"/>
<xsl:template match="LineItem">
<xsl:apply-templates select=".//Product!snapshot()/ancestor::LineItem" mode="price">
<xsl:with-param name="price" tunnel="yes" select="LineItemPrice"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="LineItem" mode="price">
<xsl:param name="price" tunnel="yes"/>
<xsl:copy>
<xsl:apply-templates select="@*, $price, node()" mode="#current"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/bFN1y8J
XSLT 3随Saxon 9.8或更高版本或Altova 2017及更高版本一起提供,因此,如果您使用最新的XSLT 2处理器,则您的处理器也可以使用XSLT 3代替标记的XSLT 2。
XSLT 2没有snapshot
,但是您当然可以尝试采用相同的方法,将每种产品推入不同的模式以在那里重构子树,现在只需要排除其他模板除Product
以外的所有内容:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="#all"
version="2.0">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()" mode="#all">
<xsl:copy>
<xsl:apply-templates select="@* | node()" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:template match="LineItem">
<xsl:apply-templates select=".//Product"/>
</xsl:template>
<xsl:template match="Product">
<xsl:apply-templates select="ancestor::LineItem" mode="price">
<xsl:with-param name="product" tunnel="yes" select="."/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="Product" mode="price">
<xsl:param name="product" tunnel="yes"/>
<xsl:if test=". is $product">
<xsl:next-match/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>