Замена пространства имен - проблема со значениями атрибута, которые имеют пространство имен
Я перехожу из одного пространства имен в другое в XML, и у меня возникли проблемы с атрибутами xsi: type для типизированных элементов. Я использовал следующий шаблон, который легко перемещает элемент с одним пространством имен в другое.
<xsl:template match="ent:*" >
<xsl:element name="ent:{local-name()}"
namespace="http://ns3">
<xsl:copy-of select="@*" />
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
но я не могу обновить значения атрибутов, которые принадлежат данному пространству имен, как атрибут xsi: type.
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ser:getAsByIdResponse xmlns:ser="http://osde.com.ar/services">
<return xmlns:xsi=".." xmlns:ns3New="http://ns3" xmlns:ns1New="http://ns2" xsi:type="nsold:aType"/>
</ser:getAsByIdResponse>
</soap:Body/>
</soap:Envelope>
В приведенном выше примере я не могу изменить "nsold: atype" на такой, как "ns3New:atype", который использует новые пространства имен. Есть ли способ сделать это настроить значения?
2 ответа
"Правильный" способ сделать это, вероятно, с помощью преобразования с учетом схемы, которое распознает xsi:type как атрибут типа (*, xs:QName). Затем вы можете сделать преобразование личности с дополнением
<xsl:template match="attribute(*, xs:QName)">
<xsl:attribute name="{local-name()}" namespace="{namespace-uri()}"
select="concat(f:new-prefix(namespace-uri-from-QName(.)),
':', local-name-from-QName(.))"/>
</xsl:template>
где f:new-prefix() - это функция, которая отображает URI пространства имен QName на префикс, который будет использоваться в новом документе.
Однако, если xsi:type является вашим единственным содержимым, чувствительным к пространству имен, вы можете просто обработать его как особый случай.
Ваша проблема здесь в том, что nsold:aType
текстовое значение атрибута; У него нет пространства имен, это просто текст. Вам нужен шаблон, который изменяет содержимое атрибута. Возможно, вам придется адаптировать его к вашим потребностям, но это должно продемонстрировать, как это сделать:
<xsl:template match="@*[starts-with(.,'nsold:')]">
<xsl:attribute name="{name()}">
<xsl:value-of select="concat('ns3New:',substring-after(.,'nsold:'))" />
</xsl:attribute>
</xsl:template>
Это просто заменяет содержимое любого атрибута текстом, начинающимся с 'nsold:', с 'ns3New:etc.' вместо.