【问题标题】:Why does my XSL strip out all the tags?为什么我的 XSL 会去除所有标签?
【发布时间】:2017-11-18 20:19:28
【问题描述】:

我有这个入站 XML(作为 Web 服务):

<?xml version="1.0" encoding="UTF-8"?><Envelope>
    <Body>
        <send_message>
            <user>
                <now>2017-11-17T13:38:11+00:00</now>
                <company>xyz.demo</company>
            </user>
            <messages>
                <message>
                    <app_host>app102.example.com</app_host>
                    <app_port>31632</app_port>
.....

我正在对它执行这个 XSL:

<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:ms="urn:schemas-microsoft-com:xslt">

<xsl:template match="//Envelope/Body/send_message/user/now">
  <now>
    <xsl:variable name="srcDateTime" select="//Envelope/Body/send_message/user/now"/>
    <xsl:variable name="srcDate" select="substring-before($srcDateTime, 'T')" />
    <xsl:variable name="outDate" select="format-date(xs:date($srcDate),'[D01].[M01].[Y0001]')"/>
    <xsl:copy-of select="$outDate"/>
  </now>
</xsl:template>
</xsl:stylesheet>

我的意图是重新格式化 &lt;now&gt;&lt;/now 标签中的日期 - 它做得很好 - 但它也会从 XML 中删除所有其他标签,当我需要它们时,我可以使用 XPath 提取数据以进行进一步操作脚步。结果是这样的:

<?xml version="1.0" encoding="UTF-8"?>



                <now xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ms="urn:schemas-microsoft-com:xslt">17.11.2017</now>
                xyz.demo


                    app102.example.com
                    31632

 .....

您可以看到所有其他标签已被完全剥离(仅留下空白),我只是不明白为什么会发生这种情况。我错过了什么(除了标签!)?

进一步解释——这些缺失的标签不是空的,它们里面有数据。如您所见,从我发布的结果来看,数据仍然存在,但缺少封闭标签。我需要将数据放回原始封闭标签中。

【问题讨论】:

  • 从不改变任何内容的身份转换开始,然后在其中添加新模板。此外,模板匹配可以简单地是 now 而不是绝对路径表达式。
  • 进一步解释——这些缺失的标签不是空的,它们里面有数据。如您所见,从我发布的结果来看,数据仍然存在,但缺少封闭标签。我需要将数据返回到原始封闭标签中。
  • @MathiasMüller - 我不知道你所说的“从不会改变任何东西的身份转换开始”是什么意思 - 我完全是 XSLT 的菜鸟,并试图通过必要的学习不得不这样做。我已经调整了绝对路径,谢谢。

标签: xml xslt


【解决方案1】:

如果你希望你的 XML 除了&lt;now&gt; 之外不被修改,你只需要添加一个身份转换:

<xsl:template match="@* | node()">
    <xsl:copy>
        <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
</xsl:template>

您的其他模板将仅在与指定 xpath //Envelope/Body/send_message/user/now 对应的节点上覆盖它。

(编辑:正如 Martin Müller 指出的那样,您应该考虑将该绝对路径减少为必要的相对路径,具体取决于您的用例,例如简单地 now 或者,如果您需要限制表达式的范围,@ 987654325@.)

【讨论】:

  • 我爱你!完全修复,提供我需要的东西(解释和解决方案)。谢谢!
  • 是的,您还应该向 OP 指出以绝对路径表达式作为模板匹配的样式表是不好的样式。请修改您的答案以明确&lt;xsl:template match="now"&gt; 是模板的正确形式。
  • 我不会说“正确”或“坏风格”,但我完全同意将 xpath 表达式限制为用例中必要的内容(其中 OP 只显示了一部分)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-18
  • 1970-01-01
  • 1970-01-01
  • 2011-09-08
  • 1970-01-01
  • 2010-09-07
  • 2011-05-15
相关资源
最近更新 更多