英文:
For xml-2-xml xslt it will output these text from no selected element
问题
以下是您的翻译结果:
我想通过XSLT将一个XML转换成另一个XML。
以下是我的输入XML:
``` xml
<?xml version='1.0' encoding='UTF-8'?>
<message>
<bo>
<root>
<payee>TMCH500000</payee>
</root>
</bo>
<docTrans>
<number>90001640</number>
<docType>SETTLEMENT</docType>
<createdOn>2023-04-12T10:21:31.231</createdOn>
</docTrans>
</message>
以下是我用来提取一些信息的XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no"/>
<xsl:template match="/message/bo/root">
<node><xsl:value-of select="payee" /></node>
</xsl:template>
</xsl:stylesheet>
使用上述XSLT,似乎只选择了一个元素。
但输出如下所示:
<node>TMCH500000</node>
90001640
SETTLEMENT
2023-04-12T10:21:31.231
期望输出:
<?xml version='1.0' encoding='UTF-8'?>
<node>TMCH500000</node>
所有这些docTrans
元素的文本也被选中了。
我想知道为什么。
这是我使用的XSLT播放器:链接,我还在一些其他在线XSLT工具中测试了它,并获得了相同的结果。
英文:
I want to transfer a xml to an another xml by xslt.
Below is my input xml:
<?xml version='1.0' encoding='UTF-8'?>
<message>
<bo>
<root>
<payee>TMCH500000</payee>
</root>
</bo>
<docTrans>
<number>90001640</number>
<docType>SETTLEMENT</docType>
<createdOn>2023-04-12T10:21:31.231</createdOn>
</docTrans>
</message>
Below is the xslt which I used to pick out some information.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no"/>
<xsl:template match="/message/bo/root">
<node><xsl:value-of select="payee" /></node>
</xsl:template>
</xsl:stylesheet>
With above xslt, seems there is only an element is selected.
But the output looks as below:
<node>TMCH500000</node>
90001640
SETTLEMENT
2023-04-12T10:21:31.231
Expected output:
<?xml version='1.0' encoding='UTF-8'?>
<node>TMCH500000</node>
All these text of the element docTrans
is selected as well.
I want to know why.
This is xslt playground which I used. I also test it in some other online xslt tool and get the same result.
答案1
得分: 1
在XSLT 3中,有内置的模板会自动触发,您可以通过声明<xsl:mode on-no-match="shallow-skip"/>
来防止这种情况,例如:
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no"/>
<xsl:mode on-no-match="shallow-skip"/>
<xsl:template match="/message/bo/root">
<node><xsl:value-of select="payee" /></node>
</xsl:template>
</xsl:stylesheet>
英文:
There are built-in templates that kick in, in XSLT 3 you can prevent that by declaring <xsl:mode on-no-match="shallow-skip"/>
e.g.
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no"/>
<xsl:mode on-no-match="shallow-skip"/>
<xsl:template match="/message/bo/root">
<node><xsl:value-of select="payee" /></node>
</xsl:template>
</xsl:stylesheet>
答案2
得分: 1
A simple solution for XSLT 1.0 is to change your template so that it matches the document root (/
) instead of matching /message/bo/root
, e.g.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no"/>
<xsl:template match="/">
<node><xsl:value-of select="/message/bo/root/payee" /></node>
</xsl:template>
</xsl:stylesheet>
NB this assumes that there's exactly one /message/bo/root/payee
; if there are more than one, the xsl:value-of
will take the string value of just the first one, and if there are zero /message/bo/root/payee
elements you'll end up with an empty <node/>
root element.
To answer your question about why your stylesheet copies those text nodes, even though your code doesn't contain any explicit instructions to copy them, it's because as well as your explicit templates, there are templates which are built in (i.e. implicit, or default templates) including this one:
<xsl:template match="text()|@*">
<xsl:value-of select="."/>
</xsl:template>
So another way to fix your original stylesheet would be to add a template that would override that built-in template, e.g.
<xsl:template match="text()"/>
英文:
A simple solution for XSLT 1.0 is to change your template so that it matches the document root (/
) instead of matching /message/bo/root
, e.g.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no"/>
<xsl:template match="/">
<node><xsl:value-of select="/message/bo/root/payee" /></node>
</xsl:template>
</xsl:stylesheet>
NB this assumes that there's exactly one /message/bo/root/payee
; if there are more than one, the xsl:value-of
will take the string value of just the first one, and if there are zero /message/bo/root/payee
elements you'll end up with an empty <node/>
root element.
To answer your question about why your stylesheet copies those text nodes, even though your code doesn't contain any explicit instructions to copy them, it's because as well as your explicit templates, there are templates which are built in (i.e. implicit, or default templates) including this one:
<xsl:template match="text()|@*">
<xsl:value-of select="."/>
</xsl:template>
So another way to fix your original stylesheet would be add a template that would override that built-in template, e.g.
<xsl:template match="text()"/>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论