2

There are a number of other questions that deal with this area, but I can't make the solutions there work

I have a transform that splits up a Spring bean file containing multiple beans into a set of files, each with one 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>

This works fine, producing files that start like this:

<!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">

In order that the file looks identical to one originally created with just one bean in it (since the file will be checked into source code management, I want only real differences), I want to change the name="beanN" attribute to name="bean0" in each file. Note that generally the bean tag can contain additional attributes as well as the class and name ones.

Nothing I've tried based on other answers here works. Mostly, I get errors about "Cannot create an attribute node whose parent is a document node" and "Cannot create an attribute node after creating a child of the containing element".

So I'm missing something obvious. What do I need to add to make this extra change?

Update: the problem seems partly to do with the xml:space="preserve". This is presumably causing text nodes to be created. With that removed, I don't get the errors so often but I still can't get the transform right

(and the output has

<beans><bean>

How do I get a linefeed between these tags? I can use indent="yes" to get the output formatted, but I really want to preserve the input format as it was originally, making changes only where I have to)

Update: One of my many attempts. This one runs, but is basically an identity transform. result-doc is commented out to make debugging easier for now. I really don't understand properly how xsl:attribute works so a decent explanation of that might help.

<?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>
4

1 回答 1

2

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

<?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>

name首先,我从原始bean标签中复制name所有属性(可能bean包括节点,因此将保留原始缩进)。

于 2013-11-22T11:35:33.377 回答