【发布时间】:2020-10-21 07:43:50
【问题描述】:
我有类似于以下代码的 XML。我的最终目标涉及更改一些节点并使用节点、存在、值剥离其他节点,然后使用 FOR XML PATH 重新创建这个新的 XML - 这一切都很好。
但是,我不知道如何只取回“次要”的行/属性,特别是 xmlns:xsi 和 xmlns:xsd)。
对于下面的示例,我如何在 Secondary 中获取命名空间属性,以便可以使用 FOR XML PATH 将其与调整后的 event/myfield/etc 结合起来?还是我需要写一个 FLWOR 来做到这一点? (如果是这样,至少在这部分有什么建议吗?)
我想要的,在最后:
<Secondary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Secondary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
然后我可以将它与我正在使用 FOR PATH XML 的其他字段结合起来,并将其提供给下游。 如果更简单,您能否将 xmlns:xsi 和 xmlns:xsd 与“值”一起拉出并将其连接起来以使其看起来相同?
DECLARE @xml TABLE (id int IDENTITY, switch_xml XML)
INSERT INTO @xml (switch_xml)
VALUES ('<MAIN>
<Secondary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<event>53</event>
<myfield>a</myfield>
</Secondary>
<Secondary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<event>56</event>
<myfield>a</myfield>
</Secondary>
</MAIN>
')
SELECT
--- ???? getting the Secondary here
Ev.Dat.query('event')
FROM @xml X OUTER APPLY switch_xml.nodes('/MAIN/Secondary') AS Ev(Dat)
更多可重现的例子:
<MAIN>
<Secondary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<event>53</event>
<myfield>string o text</myfield>
<myfield2>some other string</myfield2>
</Secondary>
<Secondary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<event>56</event>
<myfield>different string o tet</myfield>
<myfield2>and some other other strings</myfield2>
</Secondary>
</MAIN>
requested returned - 因为有一个事件 53,所以只删除事件 56 上的 myfield。如果没有事件 53 节点,您将不理会 56
<MAIN>
<Secondary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<event>53</event>
<myfield>string o text</myfield>
<myfield2>some other string</myfield2>
</Secondary>
<Secondary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<event>56</event>
<myfield></myfield>
<myfield2>and some other other strings</myfield2>
</Secondary>
</MAIN>
我的那个查询的例子,它不处理命名空间: (现在写 - 这会得到节点,只需要正确包装它以将节点组合成一个 MAIN)
SELECT
--- ???? getting the Secondary here
CONVERT(XML,(SELECT Ev.Dat.query('event') ,
CASE WHEN switch_xml.exist('/MAIN/EventData[event="56"]') = 1 AND ev.dat.value('(event)[1]','int') IN (53) THEN ev.dat.query('(myfield)[1]')
WHEN switch_xml.exist('/MAIN/EventData[event="56"]') = 0 AND ev.dat.value('(event)[1]','int') IN (53) THEN ev.dat.query('(myfield)[1]') else '' END
,Ev.Dat.query('myfield2') FOR XML PATH('Secondary'))) AS newxml
FROM @xml X OUTER APPLY switch_xml.nodes('/MAIN/Secondary') AS Ev(Dat)
【问题讨论】:
-
你的最终目标是什么?你写 What I want, in end 的部分似乎只是
<Secondary>开始标记。但仅此一项就不是格式良好的 XML... -
@Shnugo 是的,这正是我想要摆脱的。实际的最终目标涉及根据其他字段过滤某些子节点中的字段(如果文档包含具有这些特定值的子节点,则重写其他子节点),但所有这些都有效 - 我只需要使用 xsi/xsd 进行辅助,我'将使用 FOR XML PATH 将它们组合在一起以创建 XML,然后继续我的方式。
-
好吧,如果您提供minimal reproducible example 会很有帮助。一些样本作为输入和预期输出。我必须承认我不知道你真正想要什么。创建开始标签?那不是 XML,而只是看起来像 XML 的东西…… 操作现有的 XML?你的表现不足以帮助你解决这个问题......老实说,这听起来像是一个 XY 问题......
-
@Shnugo 添加。希望它能解释为什么我试图让原始请求“更简单”。
-
查看您的代码,我看到
.exist('/MAIN/EventData[event="56"]')指向不同的 XML,在上面的示例中没有<EventData>...
标签: sql-server xml xquery