对于 xml-2-xml XSLT,它将从未选择的元素中输出这些文本。

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

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>

示例fiddle

英文:

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>

Example fiddle.

答案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.

&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; indent=&quot;no&quot;/&gt;
  &lt;xsl:template match=&quot;/&quot;&gt;
    &lt;node&gt;&lt;xsl:value-of select=&quot;/message/bo/root/payee&quot; /&gt;&lt;/node&gt;
  &lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;

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 &lt;node/&gt; 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:

&lt;xsl:template match=&quot;text()|@*&quot;&gt;
  &lt;xsl:value-of select=&quot;.&quot;/&gt;
&lt;/xsl:template&gt;

So another way to fix your original stylesheet would be add a template that would override that built-in template, e.g.

&lt;xsl:template match=&quot;text()&quot;/&gt;

huangapple
  • 本文由 发表于 2023年4月19日 16:29:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76052302.html
匿名

发表评论

匿名网友

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

确定