2010-12-02 5 views
2

xslt를 사용하여 입력 XML 파일을 변환하여 xml 트리의 다른 위치에 나타날 수있는 특정 요소의 이름을 변경하려고합니다. 'OST'비어 있지 않은 네임 스페이스에서 이름을 제거하는 방법은 무엇입니까?

는 나는 다음과 같은 XML, 나는 모든을 제거 할

<catalog> 
<cd> 
    <ost:title>Empire Burlesque</ost:title> 
    <artist>Bob Dylan</artist> 
    <country>USA</country> 
    <company> 
    <ost:name>Columbia<ost:name> 
    </company> 
    <price>10.90</price> 
    <year>1985</year> 
</cd> 
</catalog> 

이 모든 요소에서 접두사를하고 XSLT를 사용으로 다른 모든 것을 유지. 예제 코드는 감사하겠습니다.

+0

4 칸을 들여 쓰거나 101010 단추를 사용하여 코드를 입력하십시오. 나는 너를 위해 그것을 고쳤다. –

+0

안녕하세요, 네. 우리는 ost의 이름 공간이 있습니다. 실제로 우리는 xml을이 ost 이름 공간을 지원하지 않는 이전 버전으로 되돌리려합니다. 답장을 보내 주셔서 감사합니다 – Hasif

+0

당신이 * 가지고있는 것이 좋지만 * 우리는 어떨까요? –

답변

2

예를 들어, 제거하려는 것보다 다른 네임 스페이스가없는 것 같습니다. 따라서 다음은 XSLT 스타일 시트의 예입니다. 모두 요소에서 네임 스페이스를 제거합니다 (ost: 제외).

<xsl:stylesheet version="1.0" 
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <!-- identity template: copy everything as is... --> 
    <xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
    </xsl:template> 

    <!-- ... except for elements, 
     create a similarly named element without a namespace --> 
    <xsl:template match="*"> 
    <xsl:element name="{local-name()}"> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

는있는 그대로 모든 것을 복사 할 identity transformation를 사용하지만 요소에 대해 동일한 로컬 이름을 가진 요소,하지만 네임 스페이스를 만드는 것을 우선합니다.

ost: 네임 스페이스를 제거하려는 경우 해당 네임 스페이스에 대한 네임 스페이스 선언을 포함하고 ost:*과 일치하도록 후자 템플릿을 변경할 수 있습니다.

0

이 변환이 가장 일반적입니다. 전역 매개 변수 내에 지정된 네임 스페이스에서 모든 요소와 특성을 제거합니다. 또한이 네임 스페이스 중 하나 모든 네임 스페이스 노드 제거합니다

이러한 변화는 다음과 같은 XML 문서에 적용
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="my:my" > 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<my:delNs> 
    <ns>some:namespace1</ns> 
    <ns>some:namespace3</ns> 
</my:delNs> 

<xsl:variable name="vdelNS" 
    select="document('')/*/my:delNs/*"/> 

<xsl:template match="*"> 
    <xsl:element name="{name()}" namespace="{namespace-uri()}"> 
    <xsl:copy-of select="namespace::*[not(.=$vdelNS)]"/> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="@*"> 
    <xsl:copy-of select="."/> 
</xsl:template> 

<xsl:template priority="10" match= 
"*[namespace-uri()=document('')/*/my:delNs/*]"> 

    <xsl:element name="{local-name()}"> 
    <xsl:copy-of select="namespace::*[not(.=$vdelNS)]"/> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:element> 
</xsl:template> 

<xsl:template match= 
"@*[namespace-uri()=document('')/*/my:delNs/*]"> 
    <xsl:attribute name="{local-name()}"> 
    <xsl:value-of select="."/> 
    </xsl:attribute> 
</xsl:template> 
</xsl:stylesheet> 

(제공된에 따라,하지만 잘 형성되도록 수정 및 포함하도록 확장 3 네임 스페이스와 그 안에 요소와 속성) : 원하는 결과가을 생산

<catalog xmlns:ost="some:namespace1" 
    xmlns:x="some:namespace2" 
    xmlns:y="some:namespace3"> 
<cd> 
    <ost:title>Empire Burlesque</ost:title> 
    <y:artist>Bob Dylan</y:artist> 
    <country>USA</country> 
    <company ost:type="big"> 
    <ost:name>Columbia</ost:name> 
    </company> 
    <x:price>10.90</x:price> 
    <year>1985</year> 
</cd> 
</catalog> 

:

,210

설명 :

  1. 처음 두 템플릿 신원 규칙과 거의 동일하지만,이<my:delNs>에 지정된 네임 스페이스에 대한 네임 스페이스 노드를 복사하지 않습니다.

  2. 마지막 두 템플릿은<my:delNs> 아래에 나열된 네임 스페이스에 속하는 모든 요소와 특성에 사용됩니다. 이 두 템플릿의 이름 만 로컬 이름으로 실제로 변경됩니다.

+0

+1 좋은 답변입니다. –

+0

@Alejandro : 감사합니다. 나는 토론 할 흥미로운 주제가 있다고 생각한다. 내 Wordpress 블로그 userid를 사용하여 Google 메일에서 찾을 수 있습니다. –

관련 문제