XSLT 从 for-each 之外的另一个变量访问元素的值
XSLT Accessing value of element from another variable outside a for-each
我的要求很可笑。我很抱歉!
我是这种令人讨厌的要求的受害者!
来源XML:
<Order>
<OrderLines>
<orderline><!-- Items may be repeated but with different instructions -->
<id>100</id>
<quantity>1</quantity>
<instruction>Instruction one</instruction>
</orderline>
<orderline>
<id>100</id>
<quantity>1</quantity>
<instruction>Instruction two</instruction>
</orderline>
<orderline>
<id>101</id>
<quantity>2</quantity>
<instruction>Some text</instruction>
</orderline>
</OrderLines>
</Order>
来源二(可以用$Order/PODetail访问)
<PODetails>
<Intro>
<seqno>001</seqno>
<text>Sometext</text>
</Intro>
<item> <!--Items will not be repeated -->
<seqno>002</seqno>
<id>100</id>
<name>COAL</name>
<Supplier>123</Supplier>
</item>
<details>
<seqno>003</seqno>
<quantity>2</quantity>
<unitprice>150</unitprice>
</details>
<item>
<seqno>004</seqno>
<id>101</id>
<name>MICA</name>
<Supplier>123</Supplier>
</item>
<details>
<seqno>005</seqno>
<quantity>2</quantity>
<unitprice>160</unitprice>
</details>
<Summary>
<seqno>006</seqno>
<text>Sometext</text>
</Summary>
</PODetails>
输出XML:
<PODetails>
<Intro>
<seqno>001</seqno>
<text>Sometext</text>
</Intro>
<item>
<seqno>002</seqno>
<id>100</id>
<name>COAL</name>
<Supplier>123</Supplier>
<instruction>Instruction one</instruction ><!--From source one-->
</item>
<details>
<seqno>003</seqno>
<quantity>1</quantity>
<unitprice>150</unitprice>
</details>
<item>
<seqno>004</seqno>
<id>100</id>
<name>COAL</name>
<Supplier>123</Supplier>
<instruction>Instruction two</instruction >
</item>
<details>
<seqno>005</seqno>
<quantity>1</quantity>
<unitprice>150</unitprice>
</details>
<item>
<seqno>006</seqno>
<id>101</id>
<name>MICA</name>
<Supplier>123</Supplier>
<instruction>some text<instruction>
</item>
<details>
<seqno>007</seqno>
<quantity>2</quantity>
<unitprice>160</unitprice>
</details>
<Summary>
<seqno>008</seqno>
<text>Sometext</text>
</Summary>
</PODetails>
说明
源一中的item
和quantity
优先(即使o/p采用源二的结构)。
原因:
源一中的项目将在源二中可用。不同之处在于,数量是针对源二中的特定数量求和的。 在来源二中查找项目 100 的总数量为 2。
原因是来源 1 可能包含相同项目的不同 instruction
,因此必须单独处理。但是,这些项目的 unitprice
等其他详细信息与源二中包含的相同。例如,项目煤有不同的说明,它们必须在输出中包含两次。然而,其他细节如 unitprice
是相同的,它们是从源二中获取的。
seqno
只是根元素 wiz., intro
, item
, detail
的每个第一级兄弟姐妹的递增数字, summary
…
- 我面临的挑战是在循环遍历源一的每个
<orderline>
时访问源二的元素。
澄清
当谈到 xslt 时,我是一个菜鸟。但是,即使我很笨,我还是推断 <item>
<details>
应该包含在 <items>
之类的东西中,但我无法更改 xsd,因为它与其他系统相关联.当我遍历每个 <orderline>
时,甚至可以访问 Source Two variable 吗?通过一些初步研究 here 我推断这是不可能的。有解决办法吗?
提前致谢!
在以下假设下:
- 您当前的节点是
orderline
,通过 template match="orderline"
或 for-each select="orderline"
- $Order 变量在范围内并且是 XPath 可用的(您同时标记了 XSLT 1.0 和 XSLT 2.0,所以我们不确定)。
然后您将查看类似这样的 XPath 来访问,比方说,unitprice
:
<xsl:value-of
select="$Order/PODetails/item[id = current()/id]
/following-sibling::details[1]/unitprice"/>
可能需要根据 $Order 变量的性质进行调整。另外,我是临时输入的,所以我没有测试错别字。
我还是不明白你的部分解释尤其是。这个:
A difference is that the quantity is summed up for a particular
quantity in source two. Find item 100's quantity summed up to 2 in
source two.
假设源文档中的每个 orderline
输出应该恰好有一个 item
(和一个伴随的 details
节点)- IOW,没有必要分组通过他们的 id 的 orderlines 并总结他们的数量 - 我建议采用以下方法:
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="*"/>
<xsl:param name="lookup-doc" select="document('source2.xml')" />
<xsl:key name="item" match="item" use="id" />
<xsl:template match="/Order">
<PODetails>
<xsl:copy-of select="$lookup-doc/PODetails/Intro"/>
<xsl:apply-templates select="OrderLines/orderline"/>
<Summary>
<seqno><xsl:value-of select="format-number(2 * count(OrderLines/orderline) + 2, '000')"/></seqno>
<xsl:copy-of select="$lookup-doc/PODetails/Summary/text"/>
</Summary>
</PODetails>
</xsl:template>
<xsl:template match="orderline">
<xsl:variable name="orderline" select="." />
<xsl:variable name="id" select="id" />
<xsl:variable name="number" select="2 * position()" />
<!-- switch context to lookup document -->
<xsl:for-each select="$lookup-doc">
<xsl:variable name="item" select="key('item', $id)" />
<item>
<seqno><xsl:value-of select="format-number($number, '000')"/></seqno>
<xsl:copy-of select="$id | $item/name | $item/Supplier | $orderline/instruction"/>
</item>
<details>
<seqno><xsl:value-of select="format-number($number + 1, '000')"/></seqno>
<xsl:copy-of select="$orderline/quantity"/>
<xsl:copy-of select="$item/following-sibling::details[1]/unitprice"/>
</details>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我的要求很可笑。我很抱歉! 我是这种令人讨厌的要求的受害者!
来源XML:
<Order>
<OrderLines>
<orderline><!-- Items may be repeated but with different instructions -->
<id>100</id>
<quantity>1</quantity>
<instruction>Instruction one</instruction>
</orderline>
<orderline>
<id>100</id>
<quantity>1</quantity>
<instruction>Instruction two</instruction>
</orderline>
<orderline>
<id>101</id>
<quantity>2</quantity>
<instruction>Some text</instruction>
</orderline>
</OrderLines>
</Order>
来源二(可以用$Order/PODetail访问)
<PODetails>
<Intro>
<seqno>001</seqno>
<text>Sometext</text>
</Intro>
<item> <!--Items will not be repeated -->
<seqno>002</seqno>
<id>100</id>
<name>COAL</name>
<Supplier>123</Supplier>
</item>
<details>
<seqno>003</seqno>
<quantity>2</quantity>
<unitprice>150</unitprice>
</details>
<item>
<seqno>004</seqno>
<id>101</id>
<name>MICA</name>
<Supplier>123</Supplier>
</item>
<details>
<seqno>005</seqno>
<quantity>2</quantity>
<unitprice>160</unitprice>
</details>
<Summary>
<seqno>006</seqno>
<text>Sometext</text>
</Summary>
</PODetails>
输出XML:
<PODetails>
<Intro>
<seqno>001</seqno>
<text>Sometext</text>
</Intro>
<item>
<seqno>002</seqno>
<id>100</id>
<name>COAL</name>
<Supplier>123</Supplier>
<instruction>Instruction one</instruction ><!--From source one-->
</item>
<details>
<seqno>003</seqno>
<quantity>1</quantity>
<unitprice>150</unitprice>
</details>
<item>
<seqno>004</seqno>
<id>100</id>
<name>COAL</name>
<Supplier>123</Supplier>
<instruction>Instruction two</instruction >
</item>
<details>
<seqno>005</seqno>
<quantity>1</quantity>
<unitprice>150</unitprice>
</details>
<item>
<seqno>006</seqno>
<id>101</id>
<name>MICA</name>
<Supplier>123</Supplier>
<instruction>some text<instruction>
</item>
<details>
<seqno>007</seqno>
<quantity>2</quantity>
<unitprice>160</unitprice>
</details>
<Summary>
<seqno>008</seqno>
<text>Sometext</text>
</Summary>
</PODetails>
说明
源一中的
item
和quantity
优先(即使o/p采用源二的结构)。 原因: 源一中的项目将在源二中可用。不同之处在于,数量是针对源二中的特定数量求和的。 在来源二中查找项目 100 的总数量为 2。 原因是来源 1 可能包含相同项目的不同instruction
,因此必须单独处理。但是,这些项目的unitprice
等其他详细信息与源二中包含的相同。例如,项目煤有不同的说明,它们必须在输出中包含两次。然而,其他细节如unitprice
是相同的,它们是从源二中获取的。seqno
只是根元素 wiz.,intro
,item
,detail
的每个第一级兄弟姐妹的递增数字,summary
…- 我面临的挑战是在循环遍历源一的每个
<orderline>
时访问源二的元素。
澄清
当谈到 xslt 时,我是一个菜鸟。但是,即使我很笨,我还是推断 <item>
<details>
应该包含在 <items>
之类的东西中,但我无法更改 xsd,因为它与其他系统相关联.当我遍历每个 <orderline>
时,甚至可以访问 Source Two variable 吗?通过一些初步研究 here 我推断这是不可能的。有解决办法吗?
提前致谢!
在以下假设下:
- 您当前的节点是
orderline
,通过template match="orderline"
或for-each select="orderline"
- $Order 变量在范围内并且是 XPath 可用的(您同时标记了 XSLT 1.0 和 XSLT 2.0,所以我们不确定)。
然后您将查看类似这样的 XPath 来访问,比方说,unitprice
:
<xsl:value-of
select="$Order/PODetails/item[id = current()/id]
/following-sibling::details[1]/unitprice"/>
可能需要根据 $Order 变量的性质进行调整。另外,我是临时输入的,所以我没有测试错别字。
我还是不明白你的部分解释尤其是。这个:
A difference is that the quantity is summed up for a particular quantity in source two. Find item 100's quantity summed up to 2 in source two.
假设源文档中的每个 orderline
输出应该恰好有一个 item
(和一个伴随的 details
节点)- IOW,没有必要分组通过他们的 id 的 orderlines 并总结他们的数量 - 我建议采用以下方法:
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="*"/>
<xsl:param name="lookup-doc" select="document('source2.xml')" />
<xsl:key name="item" match="item" use="id" />
<xsl:template match="/Order">
<PODetails>
<xsl:copy-of select="$lookup-doc/PODetails/Intro"/>
<xsl:apply-templates select="OrderLines/orderline"/>
<Summary>
<seqno><xsl:value-of select="format-number(2 * count(OrderLines/orderline) + 2, '000')"/></seqno>
<xsl:copy-of select="$lookup-doc/PODetails/Summary/text"/>
</Summary>
</PODetails>
</xsl:template>
<xsl:template match="orderline">
<xsl:variable name="orderline" select="." />
<xsl:variable name="id" select="id" />
<xsl:variable name="number" select="2 * position()" />
<!-- switch context to lookup document -->
<xsl:for-each select="$lookup-doc">
<xsl:variable name="item" select="key('item', $id)" />
<item>
<seqno><xsl:value-of select="format-number($number, '000')"/></seqno>
<xsl:copy-of select="$id | $item/name | $item/Supplier | $orderline/instruction"/>
</item>
<details>
<seqno><xsl:value-of select="format-number($number + 1, '000')"/></seqno>
<xsl:copy-of select="$orderline/quantity"/>
<xsl:copy-of select="$item/following-sibling::details[1]/unitprice"/>
</details>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>