2013-05-03 1 views
0

У меня только есть доступ к командам и функциям xpath 1.0. Мне нужно переместить объявление пространства имен из корневого узла в дочерний узел, где это пространство имен начинает использоваться.XSLT 1.0 для перемещения пространства имен дочернему узлу

Источник XML:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<Accounts xmlns:test="http:example.com/test1"> 
    <ParentAccount>10113146</ParentAccount> 
    <test1>test1</test1> 
    <test2>test2</test2> 
    <test:Siblings> 
     <test:CustomerNumber>10113146</test:CustomerNumber> 
     <test:CustomerNumber>120051520</test:CustomerNumber> 
    </test:Siblings> 
</Accounts> 

Желаемая XML:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<Accounts x> 
    <ParentAccount>10113146</ParentAccount> 
    <test1>test1</test1> 
    <test2>test2</test2> 
    <test:Siblings xmlns:test="http:example.com/test1"> 
     <test:CustomerNumber>10113146</test:CustomerNumber> 
     <test:CustomerNumber>120051520</test:CustomerNumber> 
    </test:Siblings> 
</Accounts> 

Любые яркие идеи?

ответ

2

Вот один из способов сделать это.

Когда XSLT:

<?xml version="1.0"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output omit-xml-declaration="no" indent="yes"/> 
    <xsl:strip-space elements="*"/> 

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

    <xsl:template match="Accounts"> 
    <Accounts> 
     <xsl:apply-templates /> 
    </Accounts> 
    </xsl:template> 

</xsl:stylesheet> 

... применяется против предусмотренного XML:

<?xml version="1.0" encoding="UTF-8" standalone="no"?> 
<Accounts xmlns:test="http:example.com/test1"> 
    <ParentAccount>10113146</ParentAccount> 
    <test1>test1</test1> 
    <test2>test2</test2> 
    <test:Siblings> 
    <test:CustomerNumber>10113146</test:CustomerNumber> 
    <test:CustomerNumber>120051520</test:CustomerNumber> 
    </test:Siblings> 
</Accounts> 

... производится разыскиваемый результат:

<?xml version="1.0"?> 
<Accounts> 
    <ParentAccount>10113146</ParentAccount> 
    <test1>test1</test1> 
    <test2>test2</test2> 
    <test:Siblings xmlns:test="http:example.com/test1"> 
    <test:CustomerNumber>10113146</test:CustomerNumber> 
    <test:CustomerNumber>120051520</test:CustomerNumber> 
    </test:Siblings> 
</Accounts> 

Объяснение:

Объяснение позади, почему это работает начинается с раздела от Namespaces in XML 1.0 спецификации:

Область действия объявления пространства имен объявляющего префикс простирается от начало открывающем теге в котором он отображается до конца соответствующего конечного тега, исключая область любых внутренних деклараций с той же частью NSAttName. В случае пустого тега область - это сам тег.

Такое объявление пространства имен применяется ко всем элементам и атрибутам именам в пределах своей области, префикс которых соответствует указанному в объявлении .

В двух словах это означает, что, когда пространство имен объявлено на элементе, оно фактически определено для использования во всех элементах под этой исходной областью. Кроме того, если пространство имен должно использоваться в элементе без предварительного определения в другом месте, соответствующее определение происходит в этом элементе.

Таким образом, используя свой документ и мой XSLT, давайте посмотрим, как это играет:

  1. Первый шаблон - The Identity Template - копирует все узлы и атрибуты, как есть из исходного XML в результате XML.
  2. Второй шаблон заменяет исходный элемент <Accounts> новым; кстати, этот новый элемент <Accounts>не определяет пространство имен http:example.com/test1. Наконец, этот шаблон применяет шаблоны ко всем дочерним элементам <Accounts>.
  3. Когда процессор достигает <test:Siblings>, он видит пространство имен, которое, хотя присутствует в исходном XML, не было правильно определено в результирующем документе. Таким образом, это определение добавляется к <test:Siblings>.
+0

Hello ABach, Вы можете объяснить, почему это или предоставить ссылку, которая объясняет это? У меня нет опыта работы с пространствами имен в XSLT (сначала я избавляюсь от них). Спасибо, Питер – Peter

+0

@Peter - я добавил объяснение. Дайте мне знать, если у вас возникнут дополнительные вопросы. – ABach

+0

@ABack: Спасибо +1 – Peter