如何理解特定的XSLT输出

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

How to understand the specific XSLT output

问题

I have below XML



true



AAA



BBB








```

This is my XSLT change. I need to fit this into an existing XSLT. So need do this in the below mentioned way only by using Param and for-each loop.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
    <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/root">
    <xsl:apply-templates select="Example"/>
    <xsl:call-template name="SellDetailsInfo">
      <xsl:with-param name="Example" select="Example"/>
      </xsl:call-template>
  </xsl:template>
    
  <xsl:template name="SellDetailsInfo">
    <xsl:param name="Example"/>
    <xsl:for-each select="$Example/Details">
        <xsl:value-of select="$Example/ESell"/>
        <xsl:value-of select="SellStatus"/>
      </xsl:for-each>
  </xsl:template>
  
</xsl:stylesheet>

If I check the value of $Example, it contains all the value but whenever I am checking the value if $Example/Details, its only printing 1st value but twice.

Output for $Example

true

AAA

BBB

true

AAA

BBB

Output of $Example/Details is

AAA

AAA

Output of $Example/Details/SellStatus is

AAAAAA

I am new to XSLT. I tried many ways but still not able to understand the behavior.

I will use the field $Example/Details/SellStatus in <xsl:if> to check the value. If the value will be BBB then I will add some more tag to the XML.

But this is always giving me AAA.

This is XSLT 1.0


<details>
<summary>英文:</summary>

I have below XML

<root>
<Example>
<ESell>true</ESell>
<Details>
<Item tc="101"/>
<SellStatus>AAA</SellStatus>
</Details>
<Details>
<Item tc="102"/>
<SellStatus>BBB</SellStatus>
</Details>
</Example>
<Story>
<Book tc="Horror"/>
<Cover tc="Paper"/>
<TransRef/>
</Story>
</root>


This is my XSLT change. I need to fit this into an existing XSLT. So need do this in the below mentioned way only by using Param and for-each loop.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/root">
<xsl:apply-templates select="Example"/>
<xsl:call-template name="SellDetailsInfo">
<xsl:with-param name="Example" select="Example">
</xsl:with-param>
</xsl:call-template>
</xsl:template>

<xsl:template name="SellDetailsInfo">
<xsl:param name="Example"/>
<xsl:for-each select="$Example/Details">
<xsl:value-of select="$Example"/>
<xsl:value-of select="$Example/Details"/>
</xsl:for-each>
</xsl:template>

</xsl:stylesheet>


If I check the value of $Example, it contains all the value but whenever I am checking the value if $Example/Details, its only printing 1st value but twice.

Output for $Example

true

AAA

BBB

true

AAA

BBB

Output of  $Example/Details is

AAA

AAA

Output of $Example/Details/SellStatus is

AAAAAA

I am new to XSLT. I tried many ways but still not able to understand the behavior.

I will use the field $Example/Details/SellStatus in \&lt;xsl:if\&gt; to check the value. If the value will be BBB then I will add some more tag to the XML.

But this is always giving me AAA.

This is XSLT 1.0

</details>


# 答案1
**得分**: 1

您可以删除第一个`xsl:apply-templates`,因为它会创建重复项。按名称调用模板不是必要的,但我将其保留,因为我仁慈地假设您打算组织您的(可能更复杂的)代码。我还将参数的名称从`Example`更改为`ExampleParam`以避免混淆/名称冲突。应用所有这些变更并包括一个`xsl:if`子句,您的代码可能如下所示:

```xml
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>

  <xsl:template match="/root">
    <xsl:call-template name="SellDetailsInfo">
      <xsl:with-param name="ExampleParam" select="Example" />
    </xsl:call-template>
  </xsl:template>

  <xsl:template name="SellDetailsInfo">
    <xsl:param name="ExampleParam"/>
    <xsl:for-each select="$ExampleParam/Details">
        Details: <xsl:value-of select="SellStatus"/>
        <xsl:if test="SellStatus='BBB'">
          SubDetails: <xsl:value-of select="'whatever'"/>
        </xsl:if>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

它的输出是:

Details: AAA
Details: BBB
  SubDetails: whatever
英文:

You can remove the first xsl:apply-templates, because it creates the doubles. Calling the template by name is not necessary, but I leave it there, because I benevolently assume that you intend to structure your (possibly more complex) code. I also changed the name of the parameter from Example to ExampleParam to avoid confusion/name clashes.

Applying all of this and including an xsl:if clause, your code could look like this:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;xsl:stylesheet version=&quot;1.0&quot; xmlns:xsl=&quot;http://www.w3.org/1999/XSL/Transform&quot;
    xmlns:msxsl=&quot;urn:schemas-microsoft-com:xslt&quot; exclude-result-prefixes=&quot;msxsl&quot;&gt;
    &lt;xsl:output method=&quot;xml&quot; indent=&quot;yes&quot;/&gt;
    &lt;xsl:strip-space elements=&quot;*&quot; /&gt;

  &lt;xsl:template match=&quot;/root&quot;&gt;
    &lt;xsl:call-template name=&quot;SellDetailsInfo&quot;&gt;
      &lt;xsl:with-param name=&quot;ExampleParam&quot; select=&quot;Example&quot; /&gt;
    &lt;/xsl:call-template&gt;
  &lt;/xsl:template&gt;

  &lt;xsl:template name=&quot;SellDetailsInfo&quot;&gt;
    &lt;xsl:param name=&quot;ExampleParam&quot;/&gt;
    &lt;xsl:for-each select=&quot;$ExampleParam/Details&quot;&gt;
        Details: &lt;xsl:value-of select=&quot;SellStatus&quot;/&gt;
        &lt;xsl:if test=&quot;SellStatus=&#39;BBB&#39;&quot;&gt;
          SubDetails: &lt;xsl:value-of select=&quot;&#39;whatever&#39;&quot;/&gt;
        &lt;/xsl:if&gt;
    &lt;/xsl:for-each&gt;
  &lt;/xsl:template&gt;

&lt;/xsl:stylesheet&gt;

Its output is

Details: AAA
Details: BBB
  SubDetails: whatever

答案2

得分: 1

你得到的输出可以分为两部分:

第一部分由以下指令产生:

&lt;xsl:apply-templates select=&quot;Example&quot;/&gt;

您没有匹配Example的模板,因此内置模板规则会处理Example元素并将其所有后代文本节点复制到输出以产生:

	true
	
		
		AAA
	
	
		
		BBB

第二部分是通过调用SellDetailsInfo模板生成的。该模板迭代处理两个Details元素,并为它们都生成完全相同的输出。为什么呢?因为您的xsl:value-of指令引用了$Example参数,而不是当前的Detail

因此,第一个指令:

&lt;xsl:value-of select=&quot;$Example&quot;/&gt;

返回整个Example元素的字符串值(再次是Example的所有后代文本节点的串联),而第二个指令:

&lt;xsl:value-of select=&quot;$Example/Details&quot;/&gt;

返回第一个Details元素的字符串值 - 这是因为在XSLT 1.0中,xsl:value-of指令返回所选节点集中第一个节点的字符串值。

希望这可以帮助您理解为什么会得到您看到的输出。您没有说明您希望获得什么输出,所以我不会猜测可能获取它的最佳方法。特别是因为我不理解您的限制,即“将其嵌入到现有的XSLT中”或者为什么您需要(或者认为需要)“仅使用Param和for-each循环以下述方式执行此操作”。

英文:

The output you get could be divided into 2 parts:

The first part is produced by the instruction:

&lt;xsl:apply-templates select=&quot;Example&quot;/&gt;

You do not have a template matching Example, so the built-in template rules process the Example element and copy all of its descendant text nodes to the output to produce:

	true
	
		
		AAA
	
	
		
		BBB

The 2nd part is produced by calling the SellDetailsInfo template. This template iterates over both Details elements, and produces exactly the same output for both of them. Why? Because your xsl:value-of instructions refer to the $Example parameter, not to the current Detail.

Therefore the first instruction:

&lt;xsl:value-of select=&quot;$Example&quot;/&gt;

returns the string-value of the entire Example element (which is again the concatenation of all the text node descendants of Example), and the 2nd instruction:

&lt;xsl:value-of select=&quot;$Example/Details&quot;/&gt;

returns the string-value of the first Details element - this is because in XSLT 1.0 the xsl:value-of instruction returns the string-value of the first node in the selected node-set.

Hopefully this will help you to understand why you're getting the output that you see. You did not say what output you want to get, so I am not going to guess what might be the best way to get it. Especially since I don't understand your limitation of "fit this into an existing XSLT" or why you need (or think you need) to "do this in the below mentioned way only by using Param and for-each loop."

huangapple
  • 本文由 发表于 2023年6月29日 23:27:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76582509.html
匿名

发表评论

匿名网友

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

确定