2013-09-27 3 views
0

Моя база XML, каккак изменить имя узла и скопировать данные этого узла в XML-другому, используя XSLT

<?xml version="1.0" encoding="iso-8859-1"?> 
<Report version="1.0"> 
    <sourceName Identification="xyz"/> 
    <sourcesys Identification="mycomp"> 
    <Manager> 
     <ManagerNo>1023114455</ManagerNo> 
     <Address>Delhi,India</Address> 
     <Currency> 
     <CurrencyType>Rupee</CurrencyType> 
     </Currency> 
    </Manager> 
    <Manager> 
     <ManagerNo>236784455</ManagerNo> 
     <Address>California,USA</Address> 
     <Currency> 
     <CurrencyType>Dollar</CurrencyType> 
     </Currency> 
    </Manager> 
    </sourcesys> 
</Report> 

Я хочу, чтобы преобразовать этот XML в следующий один

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<ManagerDetails xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <ManagerDetail> 
    <ManagerNo>1023114455</ManagerNo> 
    <Address> 
     <PermenantAdd>California,USA</PermenantAdd> 
    </Address> 
    <CurrencyID>Rupee</CurrencyID> 
    </ManagerDetail> 
    <ManagerDetail> 
    <ManagerNo>236784455</ManagerNo> 
    <Address> 
     <PermenantAdd>Delhi,India</PermenantAdd> 
    </Address> 
    <CurrencyID>Dollar</CurrencyID> 
    </ManagerDetail> 
</managerDetails> 

Здесь есть отображение тегов:

  • sourcesys = managerDetails
  • Менеджер = Управление rDetail
  • ManagerNo = ManagerNo
  • Адрес = PermenantAdd
  • CurrencyType = CurrencyID

Как бы вы сделать это с помощью XSLT?

+0

Является ли ваша базовая XML определенно правильной? Корневым элементом является ** a1: Report **, что означает, что он является частью пространства имен, но не отображается декларация пространства имен, что означает, что это неверно. Кроме того, элемент ** sourceName ** не имеет дочерних элементов в базовом XML, но на выходе, когда он преобразован в ** ManagerDetails **, он имеет дочерние элементы. –

+0

@TimC: извините, я забыл указать пространство имен a1: Report. вы можете считать, что он определен на время. Я сожалею о неправильном сопоставлении SourceName. Я обновил вопрос, пожалуйста, проверьте. и, пожалуйста, помогите мне написать xslt, поскольку я впервые использую xslt. совершенно новый для xsl/xml/xslt – Ganeshkumar

ответ

1

Для преобразований, как это, вы должны строить на identity template, который сам по себе копии всех узлов в вашем XSLT

<xsl:template match="@*|node()"> 
     <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

Это означает, что вам нужно только написать шаблоны для узлов, которые вы хотите преобразовать (что, сказав это, является всем элементом ManagerNo).

Превратить sourcesys (аналогично для менеджера), к примеру, вы могли бы сделать это

<xsl:template match="sourcesys"> 
    <ManagerDetails> 
     <xsl:apply-templates select="@*|node()"/> 
    </ManagerDetails> 
</xsl:template> 

Чтобы удалить элемент, такой как SourceName вы бы шаблон, который просто игнорирует его

<xsl:template match="sourceName"/> 

Для обработки адреса это slighty отличается , так как вам нужно добавить новый элемент. В этом случае, я хотел бы написать шаблон, который соответствовал его текстовый узел и добавить элемент там, например, так:

<xsl:template match="Address/text()"> 
    <PermenantAdd> 
     <xsl:value-of select="." /> 
    </PermenantAdd> 
</xsl:template> 

Наконец, для CurrencyType в CurrencyID, это прямо вперед, но вы Кроме того, необходимо будет шаблон для пропуска родителя валюты элемента, и обрабатывать его детей, так как:

<xsl:template match="Currency "> 
    <xsl:apply-templates select="@*|node()"/> 
</xsl:template> 

Попробуйте XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

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

    <xsl:template match="sourcesys"> 
     <ManagerDetails> 
     <xsl:apply-templates select="@*|node()"/> 
     </ManagerDetails> 
    </xsl:template> 

    <xsl:template match="Manager"> 
     <ManagerDetail> 
     <xsl:apply-templates select="@*|node()"/> 
     </ManagerDetail> 
    </xsl:template> 

    <xsl:template match="sourceName"/> 

    <xsl:template match="Address/text()"> 
     <PermenantAdd> 
     <xsl:value-of select="." /> 
     </PermenantAdd> 
    </xsl:template> 

    <xsl:template match="Currency"> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:template> 

    <xsl:template match="CurrencyType"> 
     <CurrencyID> 
     <xsl:apply-templates select="@*|node()"/> 
     </CurrencyID> 
    </xsl:template> 
</xsl:stylesheet> 

Также обратите внимание, что существует шаблон <xsl:template match="/*">, чтобы пропустить корневой элемент, и не имеет значения, имеет ли оно пространство имен или нет.

EDIT: Если вы не хотите, чтобы скопировать через атрибуты для sourcesys, но вместо того, чтобы использовать новые атрибуты, попробуйте заменить шаблон, как так

<xsl:template match="sourcesys"> 
     <ManagerDetails href="..."> 
     <xsl:apply-templates select="node()"/> 
     </ManagerDetails> 
    </xsl:template> 

Обратите внимание, как XSL: Наносить-шаблоны теперь не хватает @*, поэтому он не будет копироваться через любой другой атрибут.

Если вы хотите

+0

Большое вам спасибо за быстрый ответ и краткое объяснение. Я запускаю ваш xslt, но в элементе XSLT копирует атрибут «Идентификация» . Мне не нужен этот атрибут в . Вместо этого я хочу атрибут «href» с некоторым жестко заданным значением. Я попытался, но не смог его получить :( – Ganeshkumar

+0

Я сделал редактирование до конца своего ответа, чтобы показать это! Если у вас есть еще какие-либо требования, которые вы не знаете, как их решить, вероятно, лучше спросить новый вопрос теперь этот ответ принят. Спасибо! –

1

Попробуйте это:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" standalone="yes" encoding="utf-8" version="1.0"/> 

    <xsl:template match="/"> 
    <xsl:element name="ManagerDetails"> 
     <xsl:apply-templates /> 
    </xsl:element> 
    </xsl:template> 

    <xsl:template match="/Report/sourcesys/Manager"> 
    <xsl:element name="ManagerDetail"> 
     <xsl:apply-templates /> 
    </xsl:element> 
    </xsl:template> 

    <xsl:template match="/Report/sourcesys/Manager/ManagerNo"> 
    <xsl:copy-of select="."/> 
    </xsl:template> 

    <xsl:template match="/Report/sourcesys/Manager/Address"> 
    <xsl:copy> 
     <xsl:element name="PermenantAdd"> 
     <xsl:value-of select="."/> 
     </xsl:element> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="/Report/sourcesys/Manager/Currency/CurrencyType"> 
    <xsl:element name="CurrencyID"> 
     <xsl:value-of select="."/> 
    </xsl:element> 
    </xsl:template> 

    <xsl:template match="text()"></xsl:template> 

</xsl:stylesheet> 
+0

Я действительно предлагаю ваше решение. Он отлично работает согласно моему требованию. Большое спасибо за помощь мне, ребята :). Если в будущем мне нравится удалять полный xpath, указанный в совпадении, например ** **, то как это сделать? – Ganeshkumar

Смежные вопросы