英文:
How to understand the specific XSLT output
问题
I have below XML
```
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 \<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>
# 答案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:
<?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>
Its output is
Details: AAA
Details: BBB
SubDetails: whatever
答案2
得分: 1
你得到的输出可以分为两部分:
第一部分由以下指令产生:
<xsl:apply-templates select="Example"/>
您没有匹配Example
的模板,因此内置模板规则会处理Example
元素并将其所有后代文本节点复制到输出以产生:
true
AAA
BBB
第二部分是通过调用SellDetailsInfo
模板生成的。该模板迭代处理两个Details
元素,并为它们都生成完全相同的输出。为什么呢?因为您的xsl:value-of
指令引用了$Example
参数,而不是当前的Detail
。
因此,第一个指令:
<xsl:value-of select="$Example"/>
返回整个Example
元素的字符串值(再次是Example
的所有后代文本节点的串联),而第二个指令:
<xsl:value-of select="$Example/Details"/>
返回第一个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:
<xsl:apply-templates select="Example"/>
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:
<xsl:value-of select="$Example"/>
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:
<xsl:value-of select="$Example/Details"/>
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."
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论