我有一个有许多注释的XSD,应该将它们移到前面的xs:simpleTypes或xs:complexTypes的a xs:annotation / xs:documentation部分。如何使用XSLT V1.0或XSLT V2.0移动这些注释?
示例输入XSD:
<?xml version="1.0" encoding="UTF-8"?>
<xs:simpleType name="ligula">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="ultricies">
<xs:restriction base="xs:integer"/>
</xs:simpleType>
<!--
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aenean commodo ligula eget dolor. Aenean massa. Cum
-->
<xs:simpleType name="neque">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="tincidunt">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<!-- ligula, porttitor eu, consequat vitae, eleifend ac, enim. -->
<!-- Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed. -->
<!-- Integer tincidunt. Cras dapibus. Vivamus elementum -->
</xs:schema>
输出XSD应为:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="ligula">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="ultricies">
<xs:annotation>
<xs:documentation>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
Aenean commodo ligula eget dolor. Aenean massa. Cum</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:integer"/>
</xs:simpleType>
<xs:simpleType name="neque">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="tincidunt">
<xs:annotation>
<xs:documentation>ligula, porttitor eu, consequat vitae, eleifend ac, enim</xs:documentation>
<xs:documentation>Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed.</xs:documentation>
<xs:documentation>Integer tincidunt. Cras dapibus. Vivamus elementum</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string"/>
</xs:simpleType>
</xs:schema>
答案 0 :(得分:3)
以下样式表将每个评论节点转换为xs:documentation
元素。更准确地说,我在一个变量中存储紧跟在xs:simpleType
或xs:complexType
元素后面的注释节点序列:
<xsl:variable name="com" select="following-sibling::comment() except following-sibling::*[local-name() = 'simpleType' or local-name() = 'complexType'][1]/following-sibling::comment()"/>
该表达式查找作为注释节点的所有后续兄弟,并减去所有注释节点,这些注释节点是紧随其后的xs:simpleType
或xs:complexType
元素的后续兄弟(我知道,这听起来很复杂)。 / p>
如果此序列不为空:
<xsl:if test="$com">
然后,插入xs:annotation
元素,并将每个注释节点的字符串值转换为xs:documentation
元素:
<xs:annotation>
<xsl:for-each select="$com">
<xs:documentation>
<xsl:value-of select="normalize-space(.)"/>
</xs:documentation>
</xsl:for-each>
</xs:annotation>
其他细节:
<强>样式表强>
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="xs:simpleType|xs:complexType">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:variable name="com" select="following-sibling::comment() except following-sibling::*[local-name() = 'simpleType' or local-name() = 'complexType'][1]/following-sibling::comment()"/>
<xsl:if test="$com">
<xs:annotation>
<xsl:for-each select="$com">
<xs:documentation>
<xsl:value-of select="normalize-space(.)"/>
</xs:documentation>
</xsl:for-each>
</xs:annotation>
</xsl:if>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="comment()"/>
</xsl:transform>
XML输出
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:simpleType name="ligula">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="ultricies">
<xs:annotation>
<xs:documentation>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:integer"/>
</xs:simpleType>
<xs:simpleType name="neque">
<xs:restriction base="xs:string"/>
</xs:simpleType>
<xs:simpleType name="tincidunt">
<xs:annotation>
<xs:documentation>ligula, porttitor eu, consequat vitae, eleifend ac, enim.</xs:documentation>
<xs:documentation>Etiam sit amet orci eget eros faucibus tincidunt. Duis leo. Sed.</xs:documentation>
<xs:documentation>Integer tincidunt. Cras dapibus. Vivamus elementum</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string"/>
</xs:simpleType>
</xs:schema>
如果您想要进行更改,请在线here尝试此解决方案。
答案 1 :(得分:2)
尝试
<xsl:template match="xs:schema">
<xsl:copy>
<xsl:for-each-group group-starting-with="xs:simpleType|xs:complexType">
<xsl:apply-templates select="." mode="include-comments">
<xsl:with-param name="comments" select="current-group()/self::comment()"/>
</
</
</
</
<xsl:template match="*" mode="include-comments">
<xsl:param name="comments" as="comment()*"/>
<xsl:copy>
<xs:documentation>
<xsl:for-each select="$comments">
<xs:annotation><xsl:value-of select="."/>
</xsl:for-each>
</
</
</
注意:在典型的实现中,这可能具有线性性能,而Matthias的解决方案可能具有二次性能。