我想在我的 XML 檔案中復制一些節點。該檔案旨在發送到列印引擎。它考慮帶有一些行的采購訂單,對于每一行,需要列印許多標簽。該數量取決于將為該采購訂單接收的專案數量。因此,我想將該特定行的 XML 節點復制 n 次,n 等于特定行中指定的副本數。
我的源 XML:
<?xml version="1.0" encoding="utf-8"?>
<report>
<header>
<purchaseorder>KER123456</purchaseorder>
</header>
<lines>
<line>
<copies>2</copies>
<item>item1</item>
</line>
<line>
<copies>3</copies>
<item>item2</item>
</line>
</lines>
</report>
請求的結果:
<report>
<header>
<purchaseorder>KER123456</purchaseorder>
</header>
<lines>
<line>
<item>item1</item>
</line>
<line>
<item>item1</item>
</line>
<line>
<item>item2</item>
</line>
<line>
<item>item2</item>
</line>
<line>
<item>item2</item>
</line>
</lines>
</report>
我已經擺弄過我在 Stack Overflow 上找到的一個 XSLT 示例: Duplicate element x number of times with XSLT
但不幸的是我無法讓它作業。
我的 XSLT 實驗:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="copies">
<xsl:variable name="copies" select="../copies"/>
<xsl:copy-of select="."/>
<xsl:for-each select="1 to .">
<xsl:apply-templates select="$copies" mode="replicate"/>
</xsl:for-each>
</xsl:template>
<xsl:template match="line" mode="replicate">
<line>
<xsl:apply-templates select="@* except @name|node()"/>
</line>
</xsl:template>
<xsl:template match="line"/>
</xsl:stylesheet>
uj5u.com熱心網友回復:
首先,您需要一個格式良好的 XML 輸入,具有單個根元素。
然后你可以簡單地做:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="line">
<xsl:variable name="item" select="item"/>
<xsl:for-each select="1 to copies">
<line>
<xsl:copy-of select="$item"/>
</line>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
演示:https : //xsltfiddle.liberty-development.net/eiorv1b
添加:
在XSLT 1.0 中做同樣的事情:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="line" name="generate-lines">
<xsl:param name="n" select="copies"/>
<xsl:if test="$n > 0">
<xsl:copy>
<xsl:copy-of select="item"/>
</xsl:copy>
<!-- recursive call -->
<xsl:call-template name="generate-lines">
<xsl:with-param name="n" select="$n - 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
uj5u.com熱心網友回復:
XSLT 1.0
這是我的 XSLT 1.0 解決方案。在 XSLT 1.0 中,不能使用 xsl:for-each 回圈,在 select 引數中有一個范圍。相反,我對模板進行了遞回呼叫。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="line">
<xsl:call-template name="block-generator">
<xsl:with-param name="N" select="copies"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="block-generator">
<xsl:param name="N"/>
<xsl:param name="i" select="0"/>
<xsl:if test="$N > $i">
<line>
<xsl:copy-of select="item"/>
</line>
<xsl:call-template name="block-generator">
<xsl:with-param name="N" select="$N"/>
<xsl:with-param name="i" select="$i 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/368121.html
上一篇:AttributeError:模塊“xml.etree.ElementTree”沒有屬性“ElimentTree”
