XSL 匹配部分但不是全部
我从 之前的帖子中得到了一个解决方案,该解决方案由 迪米特雷·诺瓦切夫。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="my:my">
<xsl:output method="xml" version="1.0" encoding="iso-8859-1" indent="yes"/>
<xsl:key name="kPhysByName" match="KB_XMod_Modules" use="Physician"/>
<xsl:template match="/">
<result>
<xsl:apply-templates/>
</result>
</xsl:template>
<xsl:template match="/*/*/*[starts-with(name(), 'InfBy')]">
<xsl:variable name="vCur" select="."/>
<xsl:for-each select="document('doc2.xml')">
<xsl:variable name="vMod" select="key('kPhysByName', $vCur)"/>
<xsl:copy>
<items>
<item>
<label>
<xsl:value-of select="$vMod/Physician"/>
</label>
<value>
<xsl:value-of select="$vMod/XModID"/>
</value>
</item>
</items>
</xsl:copy>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
我现在需要在源 XML 中使用其他字段,并且需要完整地保留现有标签,但我在执行此操作时遇到了问题。
<instance>
<NewTag>Hello</newTag1>
<AnotherNewTag>Everyone</AnotherNewTag>
<InfBy1>Dr Phibes</InfBy1>
<InfBy2>Dr X</InfBy2>
<InfBy3>Dr Chivago</InfBy3>
</instance>
额外标签和输出,
<result xmlns:my="my:my">
HelloEveryone
<items>
<item>
<label>Dr Phibes</label>
<value>60</value>
</item>
</items>
...
它删除了我一直在尝试的
<xsl:otherwise>
<xsl:copy-of select=".">
</xsl:copy-of>
</xsl:otherwise>
但作为一个 xsl 新手,我似乎无法让它发挥作用。我有一种感觉,我找错了树!
有人有什么想法吗?
谢谢,
威尔
I have a solution from an earlier post that was kindly provided by Dimitre Novatchev.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="my:my">
<xsl:output method="xml" version="1.0" encoding="iso-8859-1" indent="yes"/>
<xsl:key name="kPhysByName" match="KB_XMod_Modules" use="Physician"/>
<xsl:template match="/">
<result>
<xsl:apply-templates/>
</result>
</xsl:template>
<xsl:template match="/*/*/*[starts-with(name(), 'InfBy')]">
<xsl:variable name="vCur" select="."/>
<xsl:for-each select="document('doc2.xml')">
<xsl:variable name="vMod" select="key('kPhysByName', $vCur)"/>
<xsl:copy>
<items>
<item>
<label>
<xsl:value-of select="$vMod/Physician"/>
</label>
<value>
<xsl:value-of select="$vMod/XModID"/>
</value>
</item>
</items>
</xsl:copy>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
I now need to use additional fields in my source XML and need the existing labels intact but I'm having problems getting this going.
<instance>
<NewTag>Hello</newTag1>
<AnotherNewTag>Everyone</AnotherNewTag>
<InfBy1>Dr Phibes</InfBy1>
<InfBy2>Dr X</InfBy2>
<InfBy3>Dr Chivago</InfBy3>
</instance>
It drops the additional labels and outputs
<result xmlns:my="my:my">
HelloEveryone
<items>
<item>
<label>Dr Phibes</label>
<value>60</value>
</item>
</items>
...
I've been experimenting a lot with
<xsl:otherwise>
<xsl:copy-of select=".">
</xsl:copy-of>
</xsl:otherwise>
but being an xsl newbie I can't seem to get this to work. I've a feeling I'm barking up the wrong tree!
Does anyone have any ideas?
Thanks,
Will
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的
NewTag
和AnotherNewTag
元素与 内置模板规则。如果你想要另一种转换,你需要声明这样的规则。那么您正在寻找身份规则
Your
NewTag
andAnotherNewTag
elements are matched by the Built-in Template Rules. If you want another kind of transformation you need to declare such rules.Then you are looking for the identity rule
这是
的副作用,它尝试结合隐含的 XSLT“默认行为”为其遇到的每个子节点查找匹配模板。在您的情况下,它会遇到
和
,但这些节点没有模板。捕获这种情况的默认行为(隐藏的默认模板)将元素的文本值复制到输出流。
的文本值为“Hello”,
的文本值为“Everyone”,因此您会看到“HelloEveryone”。如果您不想这样做,请编写自己的模板来捕获这些节点:
或者,编写一个捕获任何未处理的元素节点的模板:
如果您想复制未处理的节点不变,但仍想在其中递归应用模板对他们来说,身份模板(@Alejandro 的答案表明了这一点)是可行的方法。
This is a side-effect of
<xsl:apply-templates>
which tries to find a matching template for every child node it encounters, in conjunction with implied XSLT "default behavior".In your case, it encounters
<NewTag>
and<AnotherNewTag>
, but there are no templates for these nodes.The default behavior (the hidden default template) that catches this case copies the text value of the element to the output stream.
The text value of
<NewTag>
is "Hello", that of<AnotherNewTag>
is "Everyone", so you see "HelloEveryone".If you do not want this, write your own template that catches these nodes:
Alternatively, write one that catches any unhandled element node:
If you want to copy unhandled nodes unchanged but still want to recursively apply templates within them, the identity template (@Alejandro's answer shows it) is the way to go.