我正在尝试编写一个XSL来整理一些某些XML文件(这是Maven的POM)。我想要做的是重新排列某些顶部元素的顺序,删除一个元素并按原样复制其余元素。原始XML的一个示例是:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.sourceforge.ondex.apps</groupId>
<name>Ondex</name>
<version>0.6.0-SNAPSHOT</version>
<artifactId>installer</artifactId>
<packaging>pom</packaging>
<description>NSIS based Installer</description>
<parent>
<artifactId>apps</artifactId>
<groupId>net.sourceforge.ondex</groupId>
<version>0.6.0-SNAPSHOT</version>
</parent>
<organization>
<name>Ondex Project</name>
<url>http://www.ondex.org</url>
</organization>
<build>
...
</build>
...
</project>
这个XML几乎可以使用(使用Saxon HE-9-7-06J):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math" exclude-result-prefixes="xs math pom"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:pom="http://maven.apache.org/POM/4.0.0"
>
<xsl:output method="xml" indent="yes" />
<xsl:template match="/pom:project">
<project>
<xsl:copy-of select="@*" />
<xsl:apply-templates select="pom:modelVersion" />
<xsl:apply-templates select="pom:parent" />
<xsl:apply-templates select="pom:groupId" />
<xsl:apply-templates select="pom:artifactId" />
<xsl:apply-templates select="pom:name" />
<xsl:apply-templates select="pom:description" />
<xsl:apply-templates
select="node() except (pom:modelVersion|pom:parent|pom:groupId|pom:artifactId|pom:name|pom:description|pom:version)" />
</project>
</xsl:template>
<!-- And the usual identity transform for all other nodes -->
<xsl:template match="node()|@*">
<xsl:copy><xsl:apply-templates select="node()|@*" /></xsl:copy>
</xsl:template>
</xsl:stylesheet>
但是,输出中添加了不需要的空白行代替移动的节点(例如,请参阅描述后的行,最初我有父级):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>apps</artifactId>
<groupId>net.sourceforge.ondex</groupId>
<version>0.6.0-SNAPSHOT</version>
</parent>
<groupId>net.sourceforge.ondex.apps</groupId>
<artifactId>installer</artifactId>
<name>Ondex</name>
<description>NSIS based Installer</description>
<packaging>pom</packaging>
<organization>
<name>Ondex Project</name>
<url>http://www.ondex.org</url>
</organization>
<build>
...
</build>
...
</project>
我做错了什么?请注意,我不想使用xsl:strip-space
,因为为了便于阅读,我想保留放在原始文件中的空格。
答案 0 :(得分:0)
使用*
选择节点而不是node()
:
<xsl:template match="/pom:project">
<project>
<xsl:copy-of select="@*" />
<xsl:apply-templates select="pom:modelVersion" />
<xsl:apply-templates select="pom:parent" />
<xsl:apply-templates select="pom:groupId" />
<xsl:apply-templates select="pom:artifactId" />
<xsl:apply-templates select="pom:name" />
<xsl:apply-templates select="pom:description" />
<xsl:apply-templates
select="* except (pom:modelVersion|pom:parent|pom:groupId|pom:artifactId|pom:name|pom:description|pom:version)" />
</project>
</xsl:template>
<!-- And the usual identity transform for all other nodes -->
<xsl:template match="node()|@*">
<xsl:copy><xsl:apply-templates select="node()|@*" /></xsl:copy>
</xsl:template>
使用 XSLT 2.0 代码here
答案 1 :(得分:0)
好的,在您特此写下的答案和评论之后,我已经意识到发生了什么并找到了解决方法:
正如@ michael.hor257k所解释的,问题是匹配元素之间的换行符(例如,</parent>
和<organization>
)被XSL作为节点匹配并仅在输出中报告,导致空行
<xsl:strip-space>
是不够的,因为它会删除这些换行符以及手动插入的空白行,我想保留这些行。
但这是一个好的开始:我用以下方式预处理XML:
sed -E s/'^\s*$'/'<white-line\/>'/ pom.xml | sponge pom.xml
即,所有&#39; true&#39;白线由标签<white-line />
替换。所以,现在除了<xsl:strip-space elements="*" />
之外,将它添加到上面的XSL很容易:
<xsl:template match="pom:white-line">
<xsl:text>
</xsl:text>
</xsl:template>
可能您可能还需要remove starting/trailing blank lines,以避免他们在根元素之外填充自定义XML,从而导致错误。
感谢您的帮助!