SQL 服务器:是否可以更改复杂 XML 元素的值?

SQL Server: is it possible to change the value of a complex XML element?

我需要在 XML 元素中更改一个值 - 对于这个无类型版本,它是这样工作的:

declare @X xml=
'<translations>
  <value lang="en-US">example</value>
  <value lang="de-DE">Beispiel</value>
</translations>';

set @X.modify('replace value of (/translations/value[@lang="en-US"]/text())[1] with "replacedValue"');

select @X.value('(/translations/value[@lang="en-US"])[1]','varchar(max)');

select return "replacedValue" 用于具有属性 lang="en-US" 的 "value" 元素。

不幸的是,我必须为数据库中的 XML 属性执行此操作,该数据库的类型为以下 XML 模式:

CREATE XML SCHEMA COLLECTION [dbo].[LocaleSchema] AS N'<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"><xsd:element name="translations"><xsd:complexType><xsd:complexContent><xsd:restriction base="xsd:anyType"><xsd:sequence minOccurs="0" maxOccurs="unbounded"><xsd:element name="value"><xsd:complexType><xsd:simpleContent><xsd:extension base="xsd:string"><xsd:attribute name="lang" type="language" /></xsd:extension></xsd:simpleContent></xsd:complexType></xsd:element></xsd:sequence></xsd:restriction></xsd:complexContent></xsd:complexType></xsd:element><xsd:simpleType name="language"><xsd:restriction base="xsd:string"><xsd:enumeration value="de-DE" /><xsd:enumeration value="en-US" /></xsd:restriction></xsd:simpleType></xsd:schema>'

为了以后更好的可读性,只有 XML 模式漂亮打印:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <xsd:element name="translations">
        <xsd:complexType>
            <xsd:complexContent>
                <xsd:restriction base="xsd:anyType">
                    <xsd:sequence minOccurs="0" maxOccurs="unbounded">
                        <xsd:element name="value">
                            <xsd:complexType>
                                <xsd:simpleContent>
                                    <xsd:extension base="xsd:string">
                                        <xsd:attribute name="lang" type="language" />
                                    </xsd:extension>
                                </xsd:simpleContent>
                            </xsd:complexType>
                        </xsd:element>
                    </xsd:sequence>
                </xsd:restriction>
            </xsd:complexContent>
        </xsd:complexType>
    </xsd:element>
    <xsd:simpleType name="language">
        <xsd:restriction base="xsd:string">
            <xsd:enumeration value="de-DE" />
            <xsd:enumeration value="en-US" />
        </xsd:restriction>
    </xsd:simpleType>
</xsd:schema>

如您所见,"value" XML 元素是 复杂类型 。根据文档,modify() 函数仅对 简单类型 有效。 (此外 text() 函数仅对简单类型有效)

因此,之后 SQL 上面针对键入内容的语句 - 尝试修改时会导致错误:

declare @X xml (CONTENT [dbo].[LocaleSchema])=
'<translations>
  <value lang="en-US">example</value>
  <value lang="de-DE">Beispiel</value>
</translations>';

set @X.modify('replace value of (/translations/value[@lang="en-US"]/text())[1] with "replacedValue"');

是否有变通的建议?或任何其他更改 XML 属性的可能性? (我当然需要在现实生活中的 UPDATE 语句中使用它)

提前致谢!

这有效...

CREATE XML SCHEMA COLLECTION [dbo].[LocaleSchema] AS N'<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"><xsd:element name="translations"><xsd:complexType><xsd:complexContent><xsd:restriction base="xsd:anyType"><xsd:sequence minOccurs="0" maxOccurs="unbounded"><xsd:element name="value"><xsd:complexType><xsd:simpleContent><xsd:extension base="xsd:string"><xsd:attribute name="lang" type="language" /></xsd:extension></xsd:simpleContent></xsd:complexType></xsd:element></xsd:sequence></xsd:restriction></xsd:complexContent></xsd:complexType></xsd:element><xsd:simpleType name="language"><xsd:restriction base="xsd:string"><xsd:enumeration value="de-DE" /><xsd:enumeration value="en-US" /></xsd:restriction></xsd:simpleType></xsd:schema>';
GO

declare @X xml (CONTENT [dbo].[LocaleSchema])=
'<translations>
  <value lang="en-US">example</value>
  <value lang="de-DE">Beispiel</value>
</translations>';

set @X.modify('replace value of (/translations/value[@lang="en-US"])[1] with "replacedValue"');

SELECT @x;
GO

--clean up
--DROP XML SCHEMA COLLECTION dbo.LocaleSchema;