【问题标题】:Changing the value of an attribute with xslt使用 xslt 更改属性的值
【发布时间】:2013-11-21 20:44:44
【问题描述】:

还有许多其他问题涉及该领域,但我无法解决那里的问题

我有一个转换,它将包含多个 bean 的 Spring bean 文件拆分为一组文件,每个文件都有一个 bean

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/beans/bean" xml:space="preserve"> 
            <xsl:result-document href='{translate(normalize-space(./property[@name="name"])," ", "_")}.xml'
            doctype-public="-//SPRING//DTD BEAN//EN"
            doctype-system="http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <xsl:copy-of select="."/>
</beans>
</xsl:result-document>
</xsl:template>
</xsl:stylesheet>

这工作正常,生成这样开头的文件:

<!DOCTYPE beans
  PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <bean class="com.class.mine.Policy" name="bean1">
        <property name="name">

为了使文件看起来与最初创建的只有一个 bean 的文件相同(因为文件将被检入源代码管理,我只想要真正的差异),我想将 name="beanN" 属性更改为 @ 987654324@ 在每个文件中。请注意,通常 bean 标记可以包含附加属性以及 class 和 name 属性。

根据此处的其他答案,我没有尝试过任何方法。大多数情况下,我收到有关“无法创建其父节点是文档节点的属性节点”和“在创建包含元素的子节点后无法创建属性节点”的错误。

所以我遗漏了一些明显的东西。我需要添加什么来进行这种额外的更改?

更新:问题似乎部分与 xml:space="preserve" 有关。这可能会导致创建文本节点。删除后,我不会经常收到错误,但我仍然无法正确进行转换

(并且输出有

<beans><bean>

如何在这些标签之间获得换行符?我可以使用 indent="yes" 来格式化输出,但我真的想保留原来的输入格式,只在我必须的地方进行更改)

更新:我的许多尝试之一。这个运行,但基本上是一个身份转换。 result-doc 被注释掉以使调试更容易。我真的不明白 xsl:attribute 是如何工作的,所以一个体面的解释可能会有所帮助。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="beans/bean"> 
<!--             <xsl:result-document href='{translate(normalize-space(./property[@name="name"])," /", "_+")}.xml'
            doctype-public="-//SPRING//DTD BEAN//EN"
            doctype-system="http://www.springframework.org/dtd/spring-beans.dtd"
            omit-xml-declaration="no"> -->
<beans>
<xsl:apply-templates select="bean"/>
<xsl:copy-of select="." /> 
</beans>
<!-- </xsl:result-document> -->
</xsl:template>
 <xsl:template match="bean/@*">
      <xsl:copy>
          <xsl:attribute name="name">myvalue</xsl:attribute>
           <xsl:copy-of select="@*|node()"/>
      </xsl:copy>
   </xsl:template>
</xsl:stylesheet>

【问题讨论】:

  • 问题:为什么你觉得你需要在标签之间换行?您认为 XML 系统在某种程度上很重要吗?
  • XML 无关紧要。这确实很重要,因为这些配置要检查到 CVS 中,而 CVS 不够聪明,无法知道空格差异在 XML 中并不重要。我不希望为实际上相同的文件创建额外的 CVS 修订版 - sp 我希望最终得到相同的格式,因为对于那些不那么懒惰的开发人员逐一导出文件。
  • 答案取决于您尝试更改 bean 元素属性值的准确程度。你能发布一个sn-p吗?
  • 我可以,但正如我所说,到目前为止一切都没有奏效,所以我不确定 sn-p 会有多大帮助!
  • 谢谢。对于属性问题,您尝试过的在 XSLT 中是不可能的,这就是您遇到这些错误的原因。请参阅@Ians 答案以了解正确的方法。

标签: xml xslt xml-attribute spring-bean


【解决方案1】:

如果您想要特定的缩进,那么您必须自己插入相关的换行符和空格:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" omit-xml-declaration="yes"/>

  <xsl:template match="/">
    <xsl:apply-templates select="beans/bean" />
  </xsl:template>

  <xsl:template match="bean"> 
    <xsl:result-document href='{translate(normalize-space(./property[@name="name"])," /", "_+")}.xml'
            doctype-public="-//SPRING//DTD BEAN//EN"
            doctype-system="http://www.springframework.org/dtd/spring-beans.dtd"
            omit-xml-declaration="no">
      <xsl:text>&#10;</xsl:text><!-- newline after the DOCTYPE -->
      <beans>
        <xsl:text>&#10;    </xsl:text><!-- newline and four spaces -->
        <bean>
          <xsl:copy-of select="@*" />
          <xsl:attribute name="name">bean0</xsl:attribute>
          <xsl:copy-of select="node()" />
        </bean>
        <xsl:text>&#10;</xsl:text><!-- newline between </bean> and </beans> -->
      </beans>
    </xsl:result-document>
  </xsl:template>
</xsl:stylesheet>

对于重命名:

        <bean>
          <xsl:copy-of select="@*" />
          <xsl:attribute name="name">bean0</xsl:attribute>
          <xsl:copy-of select="node()" />
        </bean>

首先我从原始bean 标记中复制所有属性(可能包括name),然后创建一个(另一个)name 属性,该属性将覆盖已复制的属性,然后最后复制所有子节点原始bean 元素(包括元素、cmets 和 文本节点,因此将保留原始缩进)。

【讨论】:

  • 谢谢。看起来很到位。我仍然不太明白属性的副本和 xsl:attribute 是如何工作的 - 复制(或定义)属性被放在父节点中,似乎?但它有效!
  • 啊。在测试示例上尝试过,一切正常。在另一个示例中运行它,所有文件在一行中都有 bean 节点(和子节点):(即使在源代码中它们位于多行/缩进。有什么想法吗?
  • 好吧,惊慌失措,这是撒克逊人的“特色”。我在没有 DTD 参考的情况下进行了测试(因为从 Eclipse 启动时我无法弄清楚如何让 Saxon 使用代理),但是我后来使用 DTD 运行了(并且在公司 VPN 之外) - 如果有的话,Saxon 会做一些不同的事情是 DTD “默认情况下,如果存在 DTD 或模式,则从 StreamSource 或 SAXSource 加载的任何源文档中删除可忽略的空白。”幸运的是,这可以改变。 (stripWhitespace=none)
  • @Paul 特定位的空白是否“可忽略”是由 DTD 定义的 - 如果您没有 DTD,那么根据定义,就没有“可忽略的空白”。
  • 谢谢。我只是没想到 DTD 的存在与否会对空白产生影响。 Saxon 帮助并不暗示它是 DTD 功能,而是暗示它是 Saxon 功能。不过,现在我知道了,没问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多