特定的XSLT场景

huangapple go评论85阅读模式
英文:

Specific Scenario in XSLT

问题

Here is the translation of the provided content:

我删除了先前的帖子以使其更清晰。

输入 XML

<Org>
<Name>OrgName</Name>
<Type>OrgType</Type>
<Customer>OrgCust</Customer>
<Product>
<ProductData>
<ID>ID1</ID>
<Name>Prod1</Name>
<Grade>Grade1</Grade>
<Number>13</Number>
</ProductData>
<ProductData>
<ID>ID2</ID>
<Name>Prod2</Name>
<Grade>Grade2</Grade>
<Number>12</Number>
</ProductData>
<ProductData>
<ID>ID3</ID>
<Name>Prod3</Name>
<Grade>Grade3</Grade>
<Number>10</Number>
</ProductData>
</Product>
<Market>TestMarket</Market>
<Quality>Tested</Quality>
<Score>70</Score>
</Org>


要求是根据\&lt;Number\&gt;标签值大于10,在组Product/ProductData中添加名为\&lt;Status\&gt;Done\&lt;/Status\&gt;的节点。

如果XML中存在ID3且\&lt;Number\&gt;大于10,则应仅向ID3添加\&lt;Status\&gt;Done\&lt;/Status\&gt;标签。

如果ID3无效(\&lt;Number\&gt;不大于10),且XML中存在ID1和ID2且有效(\&lt;Number\&gt;大于10),则应向ID2添加\&lt;Status\&gt;Done\&lt;/Status\&gt;标签。

否则,如果ID2和ID3均无效(\&lt;Number\&gt;不大于10),而ID1有效(\&lt;Number\&gt;大于10),则应向ID1添加\&lt;Status\&gt;Done\&lt;/Status\&gt;标签。

ID1、ID2和ID3的出现次数不固定。

以下是我的XSLT。在这里,我发现难以实现第二点,即ID1和ID2都有效。我需要一个全局变量,并设置该变量的值,如果一个验证匹配。然后,在循环内检查变量的值,并跳过所有其他验证。我尝试了许多方法,但无法弄清楚这一点。我查看了许多帖子,但没有提到在for-each中使用标志或在条件满足时中断循环。对此方面的任何指导都将非常有帮助。

<xsl:template match="Org/Product">
<xsl:for-each select="ProductData">
<xsl:choose>
<xsl:when test="ID ='ID1' and Number>10">
<Status>Done</Status>
</xsl:when>
<xsl:when test="ID ='ID2' and Number>10">
<Status>Done</Status>
</xsl:when>
<xsl:when test="ID ='ID3' and Number>10">
<Status>Done</Status>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>


我正在寻找的输出如下:

<Org>
<Name>OrgName</Name>
<Type>OrgType</Type>
<Customer>OrgCust</Customer>
<Product>
<ProductData>
<ID>ID1</ID>
<Name>Prod1</Name>
<Grade>Grade1</Grade>
<Number>13</Number>
</ProductData>
<ProductData>
<ID>ID2</ID>
<Name>Prod2</Name>
<Grade>Grade2</Grade>
<Number>12</Number>
<Status>Done</Status>
</ProductData>
<ProductData>
<ID>ID3</ID>
<Name>Prod3</Name>
<Grade>Grade3</Grade>
<Number>10</Number>
</ProductData>
</Product>
<Market>TestMarket</Market>
<Quality>Tested</Quality>
<Score>70</Score>
</Org>


XSLT版本为1.0。请帮助。

请告诉我您需要的进一步帮助。

英文:

I deleted the previous post to make it more clear.

Input XML

&lt;Org&gt;
  &lt;Name&gt;OrgName&lt;/Name&gt;
  &lt;Type&gt;OrgType&lt;/Type&gt;
  &lt;Customer&gt;OrgCust&lt;/Customer&gt;
  &lt;Product&gt;
    &lt;ProductData&gt;
      &lt;ID&gt;ID1&lt;/ID&gt;
      &lt;Name&gt;Prod1&lt;/Name&gt;
      &lt;Grade&gt;Grade1&lt;/Grade&gt;
      &lt;Number&gt;13&lt;/Number&gt;
    &lt;/ProductData&gt;
    &lt;ProductData&gt;
      &lt;ID&gt;ID2&lt;/ID&gt;
      &lt;Name&gt;Prod2&lt;/Name&gt;
      &lt;Grade&gt;Grade2&lt;/Grade&gt;
      &lt;Number&gt;12&lt;/Number&gt;
    &lt;/ProductData&gt;
  &lt;ProductData&gt;
      &lt;ID&gt;ID3&lt;/ID&gt;
      &lt;Name&gt;Prod3&lt;/Name&gt;
      &lt;Grade&gt;Grade3&lt;/Grade&gt;
      &lt;Number&gt;10&lt;/Number&gt;
    &lt;/ProductData&gt;
  &lt;/Product&gt;
  &lt;Market&gt;TestMarket&lt;/Market&gt;
  &lt;Quality&gt;Tested&lt;/Quality&gt;
  &lt;Score&gt;70&lt;/Score&gt;
&lt;/Org&gt;

The requirement is to add a node called &lt;Status&gt;Done&lt;/Status&gt; to the group Product/ProductData based on the &lt;Number&gt; tag value greater than 10.

If ID3 present in XML and &lt;Number&gt; is greater than 10. The &lt;Status&gt;Done&lt;/Status&gt; tag should be added in ID3 only.

If ID3 not valid (&lt;Number&gt; not greater than 10) and ID1 and ID2 both are present in XML and valid (&lt;Number&gt; greater than 10) then add the &lt;Status&gt;Done&lt;/Status&gt; tag in ID2.

Else if ID2 and ID3 are not valid (&lt;Number&gt; greater than 10) and ID1 is valid (&lt;Number&gt; greater than 10) then add the &lt;Status&gt;Done&lt;/Status&gt; tag to ID1.

Occurrence of ID1, ID2 and ID3 are not fixed.

Below is my XSLT. Here I am finding this difficult to implement the 2nd point which is ID1 and ID2 both valid. I need a global variable and set the value of that variable if one validation match. Then I will check the value of the variable with in loop and skip all other validation. I have tried many ways but not able to figure this out. I went through many posts but no where its mentioned either to use of a flag in for-each or breaking the loop if the condition satisfied. Any guidance on this will be very helpful.

&lt;xsl:template match=&quot;Org/Product&quot;&gt;


  &lt;xsl:for-each select=&quot;ProductData&quot;&gt;
    &lt;xsl:choose&gt;
      &lt;xsl:when test=&quot;ID =&#39;ID1&#39; and Number&gt;10&quot;&gt;
        &lt;Status&gt;Done&lt;/Status&gt;
      &lt;/xsl:when&gt;
      &lt;xsl:when test=&quot;ID =&#39;ID2&#39; and Number&gt;10&quot;&gt;
        &lt;Status&gt;Done&lt;/Status&gt;
      &lt;/xsl:when&gt;
      &lt;xsl:when test=&quot;ID =&#39;ID3&#39; and Number&gt;10&quot;&gt;
      &lt;Status&gt;Done&lt;/Status&gt;
      &lt;/xsl:when&gt;

    &lt;/xsl:choose&gt;

  &lt;/xsl:for-each&gt;

&lt;/xsl:template&gt;

The output I am looking for is below

&lt;Org&gt;
  &lt;Name&gt;OrgName&lt;/Name&gt;
  &lt;Type&gt;OrgType&lt;/Type&gt;
  &lt;Customer&gt;OrgCust&lt;/Customer&gt;
  &lt;Product&gt;
    &lt;ProductData&gt;
      &lt;ID&gt;ID1&lt;/ID&gt;
      &lt;Name&gt;Prod1&lt;/Name&gt;
      &lt;Grade&gt;Grade1&lt;/Grade&gt;
      &lt;Number&gt;13&lt;/Number&gt;
    &lt;/ProductData&gt;
    &lt;ProductData&gt;
      &lt;ID&gt;ID2&lt;/ID&gt;
      &lt;Name&gt;Prod2&lt;/Name&gt;
      &lt;Grade&gt;Grade2&lt;/Grade&gt;
      &lt;Number&gt;12&lt;/Number&gt;
      &lt;Status&gt;Done&lt;/Status&gt;
    &lt;/ProductData&gt;
  &lt;ProductData&gt;
      &lt;ID&gt;ID3&lt;/ID&gt;
      &lt;Name&gt;Prod3&lt;/Name&gt;
      &lt;Grade&gt;Grade3&lt;/Grade&gt;
      &lt;Number&gt;10&lt;/Number&gt;
    &lt;/ProductData&gt;
  &lt;/Product&gt;
  &lt;Market&gt;TestMarket&lt;/Market&gt;
  &lt;Quality&gt;Tested&lt;/Quality&gt;
  &lt;Score&gt;70&lt;/Score&gt;
&lt;/Org&gt;

The version for XSLT is 1.0. Please help.

答案1

得分: 0

尝试可能类似以下的内容:

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:variable name="id">
    <xsl:variable name="product" select="/Org/Product/ProductData" />
    <xsl:choose>
        <xsl:when test="$product[ID='ID3']/Number > 10">ID3</xsl:when>
        <xsl:when test="$product[ID='ID2']/Number > 10">ID2</xsl:when>
        <xsl:when test="$product[ID='ID1']/Number > 10">ID1</xsl:when>
    </xsl:choose>
</xsl:variable>

<xsl:template match="ProductData">
    <xsl:copy>
        <xsl:apply-templates/>
        <xsl:if test="ID = $id">
            <Status>Done</Status>
        </xsl:if>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

如果我们可以确定输入中列出ProductData的顺序(或者至少如果它们可以按所需顺序的某些属性进行排序),我们可以更简单地定义id变量,例如:

<xsl:variable name="id" select="/Org/Product/ProductData[Number > 10][last()]/ID" />
英文:

Try perhaps something like:

XSLT 1.0

&lt;xsl:stylesheet version=&quot;1.0&quot; 
xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;&gt;
&lt;xsl:output method=&quot;xml&quot; version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; indent=&quot;yes&quot;/&gt;
&lt;xsl:strip-space elements=&quot;*&quot;/&gt;

&lt;!-- identity transform --&gt;
&lt;xsl:template match=&quot;@*|node()&quot;&gt;
	&lt;xsl:copy&gt;
		&lt;xsl:apply-templates select=&quot;@*|node()&quot;/&gt;
	&lt;/xsl:copy&gt;
&lt;/xsl:template&gt;

&lt;xsl:variable name=&quot;id&quot;&gt;
	&lt;xsl:variable name=&quot;product&quot; select=&quot;/Org/Product/ProductData&quot; /&gt;
	&lt;xsl:choose&gt;
		&lt;xsl:when test=&quot;$product[ID=&#39;ID3&#39;]/Number &gt; 10&quot;&gt;ID3&lt;/xsl:when&gt;
		&lt;xsl:when test=&quot;$product[ID=&#39;ID2&#39;]/Number &gt; 10&quot;&gt;ID2&lt;/xsl:when&gt;
		&lt;xsl:when test=&quot;$product[ID=&#39;ID1&#39;]/Number &gt; 10&quot;&gt;ID1&lt;/xsl:when&gt;
	&lt;/xsl:choose&gt;
&lt;/xsl:variable&gt;

&lt;xsl:template match=&quot;ProductData&quot;&gt;
	&lt;xsl:copy&gt;
		&lt;xsl:apply-templates/&gt;
		&lt;xsl:if test=&quot;ID = $id&quot;&gt;
			&lt;Status&gt;Done&lt;/Status&gt;
		&lt;/xsl:if&gt;
	&lt;/xsl:copy&gt;
&lt;/xsl:template&gt;

&lt;/xsl:stylesheet&gt;

If we could be certain of the order in which ProductData are listed in the input (or at least if they could be sorted by some property in the wanted order), we could define the id variable much more simply - e.g:

&lt;xsl:variable name=&quot;id&quot; select=&quot;/Org/Product/ProductData[Number &gt; 10][last()]/ID&quot; /&gt;

huangapple
  • 本文由 发表于 2023年6月8日 17:45:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76430571.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定