2015-04-24 3 views
0

У меня есть XML-код, который мне нужно перевести через XSLT (добавлять и добавлять значения пространства имен на определенные элементы), который, кажется, работает нормально в большинстве случаев. Тем не менее, я бегу в проблему следующим кодом:Соответствие XSLT для преобразования элементов XML

XML:

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
<s:Body> 
<PatientLookupResponse xmlns="urn:Epic-com:EMPI.2012.Services.Patient"> 
<PatientLookupResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
<Patients> 
<Addresses> 
</Addresses> 
<HistoricalIDs/> 
</Patients> 
</PatientLookupResult> 
</PatientLookupResponse> 
</s:Body> 
</s:Envelope> 

XLST:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:a="urn:Epic-com:EMPI.2012.Services.External"> 
<xsl:output method="xml" indent="yes"/> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 
<xsl:template match="HistoricalIDs"> 
    <HistoricalIDs xmlns:a="urn:Epic-com:EMPI.2012.Services.External"> 
     <xsl:apply-templates select="@*|node()"/> 
    </HistoricalIDs> 
</xsl:template> 
<xsl:template match="HistoricalIDs/IDType"> 
    <a:IDType> 
     <xsl:apply-templates select="@*|node()"/> 
    </a:IDType> 
</xsl:template> 
<xsl:template match="HistoricalIDs/IDType/ID"> 
    <a:ID> 
     <xsl:apply-templates select="@*|node()"/> 
    </a:ID> 
</xsl:template> 
<xsl:template match="HistoricalIDs/IDType/Type"> 
    <a:Type> 
     <xsl:apply-templates select="@*|node()"/> 
    </a:Type> 
</xsl:template> 
</xsl:stylesheet> 

Результат:

<?xml version="1.0" encoding="UTF-8"?> 
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> 
<s:Body> 
    <PatientLookupResponse xmlns="urn:Epic-com:EMPI.2012.Services.Patient"> 
    <PatientLookupResult xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
     <Patients> 
      <Addresses> 
      </Addresses> 
      <HistoricalIDs/> 
     </Patients> 
    </PatientLookupResult> 
    </PatientLookupResponse> 
</s:Body> 
</s:Envelope> 

мне нужно иметь полученный XML-результат <HistoricalIDs xmlns:a="urn:Epic-com:EMPI.2012.Services.External"/>. Проблема в том, что он оставляет этот элемент таким же, как в исходном сообщении. Перевод действительно работает, когда <PatientLookupResponse xmlns="urn:Epic-com:EMPI.2012.Services.Patient"> и </PatientLookupResponse> нет в исходном сообщении. Однако, когда этот элемент существует, перевод не выполняется. Как я могу получить правильный перевод с текущим исходным сообщением?

ответ

0

Проблема из-за PatientLookupResponse ...

<PatientLookupResponse xmlns="urn:Epic-com:EMPI.2012.Services.Patient"> 

Это пространство имен по умолчанию объявленную на нем, а это значит, что PatientLookupResponse элемент, и все потомки узла (если не переопределяется) принадлежат этому пространству имен. Это означает, что HistoricalIDs также является частью этого пространства имен, а узел принадлежит пространству имен, не совпадает с узлом с тем же именем, который не принадлежит пространству имен.

Решение объявить пространство имен в вашем XSLT с префиксом по вашему выбору:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:a="urn:Epic-com:EMPI.2012.Services.External" 
    xmlns:p="urn:Epic-com:EMPI.2012.Services.Patient" 

Затем использовать этот префикс пространства имен для соответствия узлов в этом пространстве имен

<xsl:template match="p:HistoricalIDs"> 

Однако, вы можете обнаружить, когда вы сделаете это, что HistoricalIDs будет выводиться следующим образом:

<HistoricalIDs xmlns="" xmlns:a="urn:Epic-com:EMPI.2012.Services.External"/> 

Это связано с тем, что вы создаете новый элемент HistoricalIDs на своем выходе, который не имеет пространства имен. Таким образом, можно либо использовать префикс пространства имен в создании вывода тоже:

<xsl:template match="p:HistoricalIDs"> 
    <p:HistoricalIDs xmlns:a="urn:Epic-com:EMPI.2012.Services.External"> 
     <xsl:apply-templates select="@*|node()"/> 
    </p:HistoricalIDs> 
</xsl:template> 

Или вы могли бы объявить пространство имен по умолчанию в вашем XSLT тоже, который будет применяться к любым элементам вам выход без префикса

Try этот XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:a="urn:Epic-com:EMPI.2012.Services.External" 
    xmlns:p="urn:Epic-com:EMPI.2012.Services.Patient" 
    exclude-result-prefixes="p"> 
<xsl:output method="xml" indent="yes"/> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="p:HistoricalIDs" xmlns="urn:Epic-com:EMPI.2012.Services.Patient"> 
    <HistoricalIDs xmlns:a="urn:Epic-com:EMPI.2012.Services.External"> 
     <xsl:apply-templates select="@*|node()"/> 
    </HistoricalIDs> 
</xsl:template> 

<xsl:template match="p:HistoricalIDs/p:IDType"> 
    <a:IDType> 
     <xsl:apply-templates select="@*|node()"/> 
    </a:IDType> 
</xsl:template> 

<xsl:template match="p:HistoricalIDs/p:IDType/p:ID"> 
    <a:ID> 
     <xsl:apply-templates select="@*|node()"/> 
    </a:ID> 
</xsl:template> 

<xsl:template match="p:HistoricalIDs/p:IDType/p:Type"> 
    <a:Type> 
     <xsl:apply-templates select="@*|node()"/> 
    </a:Type> 
</xsl:template> 
</xsl:stylesheet> 
Смежные вопросы