将属性值分配给XML中的元素内容(使用XSD或XSL)

时间:2017-04-07 18:47:07

标签: xml xslt xsd

我有一个文档要求某些标题具有标准名称,而其他标题则留给作者。为了区分差异,我创建了一个属性" hardTitle"。如果hardTitle属性具有值,则title元素应显示hardTitle的值并将其锁定为不被编辑。如果hardTitle属性为空,则作者可以使用他们喜欢的任何标题。

我尝试使用枚举值(下面的代码),但这只会告诉我该值是否不正确 - 它不会填充元素中的值,也不会锁定元素内容被编辑。

我想要的是什么:

<chapter>
    <title hardTitle="Scope">Scope</title> [auto-populated from hardTitle and locked]
    ...
    <title>This Title Can Be Anything</title>
    ...
     <title hardTitle="NewT">NewT</title> [auto-populated from hardTitle and locked]
</chapter>

这是我到目前为止的代码。我知道xs:限制是将文本限制为枚举值...但是我正在寻找能够根据属性强制内容然后将其从编辑中锁定的内容。

.xsd文件摘要:

<xs:element name="title" type="editableTitle">
        <xs:alternative test="if(@hardTitle)" type="lockedTitle" />
    </xs:element>

    <xs:complexType name="editableTitle">
        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="hardTitle" />
            </xs:extension> 
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="lockedTitle">
        <xs:simpleContent>
            <xs:restriction base="editableTitle">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value="@hardTitle" />
                    </xs:restriction>
                </xs:simpleType>
            </xs:restriction>
        </xs:simpleContent>
    </xs:complexType>

2 个答案:

答案 0 :(得分:0)

您的约束可以通过title上的XSD 1.1断言表示,

<xs:assert test="not(@hardTitle) or . = @hardTitle"/>

表示必须没有@hardTitle属性,或者title的字符串值必须等于@hardTitle的值。

您的约束无法在XSD 1.0中表示。

答案 1 :(得分:0)

您可以通过这个简单的XSL转换将输入文档转换为满足约束的不同文档,从而应用

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

  <xsl:template match="title[@hardTitle]">
    <xsl:copy>
      <!-- supposes that <title> elements will not have child elements -->
      <xsl:apply-templates select="@*" />
      <xsl:value-of select="@hardTitle" />
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>