T-SQL метод xquery .modify с использованием подстановочного знака
Я работаю в SQL Server 2014. Я создал хранимую процедуру, которая выполняет ее обработку, и в конце принимает окончательный вывод запроса и форматирует его как XML. Из-за природы логики в процедуре, иногда узел должен быть удален из окончательного XML-вывода. Вот пример вывода XML (для краткости я не включил корневые узлы; надеюсь, они не потребуются для ответа на мой вопрос):
<DALink>
<InteractingIngredients>
<InteractingIngredient>
<IngredientID>1156</IngredientID>
<IngredientDesc>Lactobacillus acidophilus</IngredientDesc>
<HICRoot>Lactobacillus acidophilus</HICRoot>
<PotentiallyInactive>Not necessary</PotentiallyInactive>
<StatusCode>Live</StatusCode>
</InteractingIngredient>
</InteractingIngredients>
<ActiveProductsExistenceCode>Exist</ActiveProductsExistenceCode>
<IngredientTypeBasisCode>1</IngredientTypeBasisCode>
<AllergenMatch>Lactobacillus acidophilus</AllergenMatch>
<AllergenMatchType>Ingredient</AllergenMatchType>
</DALink>
<ScreenDrug>
<DrugID>1112894</DrugID>
<DrugConceptType>RxNorm_SemanticClinicalDr</DrugConceptType>
<DrugDesc>RxNorm LACTOBACILLUS ACIDOPHILUS/PECTIN ORAL capsule</DrugDesc>
<Prospective>true</Prospective>
</ScreenDrug>
В этой процедуре у меня есть код, который просматривает структуру XML выше и удаляет узел, когда его там не должно быть, потому что легче изменить XML, чем настроить вывод запроса. Вот пример этого кода:
SET @xml_Out.modify('declare namespace ccxsd="http://schemas.foobar.com/CC/v1_3"; delete //ccxsd:InteractingIngredients[../../../ccxsd:ScreenDrug/ccxsd:DrugConceptType="OneThing"]');
SET @xml_Out.modify('declare namespace ccxsd="http://schemas.foobar.com/CC/v1_3"; delete //ccxsd:InteractingIngredients[../../../ccxsd:ScreenDrug/ccxsd:DrugConceptType="AnotherThing"]');
SET @xml_Out.modify('declare namespace ccxsd="http://schemas.foobar.com/CC/v1_3"; delete //ccxsd:InteractingIngredients[../../../ccxsd:ScreenDrug/ccxsd:DrugConceptType="SomethingElse"]');
SET @xml_Out.modify('declare namespace ccxsd="http://schemas.foobar.com/CC/v1_3"; delete //ccxsd:InteractingIngredients[../../../ccxsd:ScreenDrug/ccxsd:DrugConceptType="SomethingElseAgain"]');
SET @xml_Out.modify('declare namespace ccxsd="http://schemas.foobar.com/CC/v1_3"; delete //ccxsd:InteractingIngredients[../../../ccxsd:ScreenDrug/ccxsd:DrugConceptType="RxNorm*"]');
Последняя команда, которую я не могу понять, как заставить работать. Все, что мне нужно сделать, - это искать случаи, когда элемент "DrugConceptType" начинается со строки "RxNorm", поскольку существует несколько версий строки, которые могут возникнуть.
У меня есть Googled и StackOverFlowed, но, возможно, из-за моей неопытности в этой области я не правильно задал вопрос.
Есть ли относительно простой способ переписать последний оператор.modify выше, чтобы использовать подстановочный знак после "RxNorm"?
1 ответ
Ваше сокращение корневого узла является проблемой на самом деле, так как вы используете пространство имен "ccxsd", а ваш XML не показывает этого.
Во всяком случае, лучше, чем написать declare namespace ...
снова и снова, это было первой строкой вашего заявления:
;WITH XMLNAMESPACES('http://schemas.fdbhealth.com/CC/v1_3' AS ccxsd)
Ну как .modify()
это вызов одного оператора, это не имеет такого значения...
Но на ваш вопрос о подстановочных
Это удалит все узлы, где содержимое элемента начинается с "RxNorm":
SET @xml.modify('delete //*[fn:substring(.,1,6)="RxNorm"]');
Помните о пропущенных пространствах имен... Не могу проверить это...
РЕДАКТИРОВАТЬ: упрощенный рабочий пример:
Вы должны проверить это с вашим фактическим XML (с корнем и пространством имен)
DECLARE @xml_Out XML=
'<DALink>
<InteractingIngredients>
<InteractingIngredient>
<IngredientID>1156</IngredientID>
<IngredientDesc>Lactobacillus acidophilus</IngredientDesc>
<HICRoot>Lactobacillus acidophilus</HICRoot>
<PotentiallyInactive>Not necessary</PotentiallyInactive>
<StatusCode>Live</StatusCode>
</InteractingIngredient>
</InteractingIngredients>
<ActiveProductsExistenceCode>Exist</ActiveProductsExistenceCode>
<IngredientTypeBasisCode>1</IngredientTypeBasisCode>
<AllergenMatch>Lactobacillus acidophilus</AllergenMatch>
<AllergenMatchType>Ingredient</AllergenMatchType>
</DALink>
<ScreenDrug>
<DrugID>1112894</DrugID>
<DrugConceptType>RxNorm_SemanticClinicalDr</DrugConceptType>
<DrugDesc>RxNorm LACTOBACILLUS ACIDOPHILUS/PECTIN ORAL capsule</DrugDesc>
<Prospective>true</Prospective>
</ScreenDrug>';
SET @xml_Out.modify('delete //InteractingIngredients[fn:substring((../../ScreenDrug/DrugConceptType)[1],1,6)="RxNorm"]');
SELECT @xml_Out;