2017-12-14 13 views
-1

null 노드를 삭제할 필요가 있지만 특정 속성 "DELETE"의 값으로 공백이있는 노드를 유지해야합니다. XSL에 익숙하지 않습니다 ... null 값을 제거하지만 공간 값을 유지하려면 어떻게해야합니까?XSL - 공백 태그 제거 및 공백 보유

"DELETE"동작이있는 노드에만 적합합니다. 예를 들어, 조치가 "DELETE"일 때 다른 노드 이름이 무엇이든 상관없이 (변경 될 것이므로) 널 값의 하위 노드는 삭제되어야합니다. 이것이 가능하지 않다면, 전체 XML 파일에서 null 값을 제거해야합니다.이 코드는 작동하고 아래에 나열되어 있습니다. 그러나 공백을 유지하지 않으며 "DELETE"속성 만위한 것이 아닙니다. 아래의 예.

<?xml version="1.0" encoding="utf-8"?> 
<test xmlns:n0="http://mynamespace"> 
<Value Action="DELETE"> 
    <Example1> </Example1> 
    <Test2 /> 
    <Example3></Example3> 
</Value> 
<Value Action="UPDATE"> 
    <space> </space> 
    <null /> 
    <null2></null2> 
</Value> 
</test> 

예상 결과 :

<?xml version="1.0" encoding="utf-8"?> 
<test xmlns:n0="http://mynamespace"> 
    <Value Action="DELETE"> 
    <Example1> </Example1> 
    </Value> 
    <Value Action="UPDATE"> 
    <space> </space> 
    <null /> 
    <null2></null2> 
    </Value> 
</test> 

모든 널 (null)을 제거

<?xml version="1.0" encoding="UTF-8"?> 

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
version="1.0"> 
    <xsl:strip-space elements="*"/> 

    <xsl:template match="*"> 
    <xsl:if test=". != '' or ./@* != ''"> 
     <xsl:element name="{local-name()}"> 
      <xsl:apply-templates select="@* | node()" /> 
     </xsl:element> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template match="@*"> 
     <xsl:attribute name="{local-name()}"> 
      <xsl:value-of select="." /> 
     </xsl:attribute> 
    </xsl:template> 
     <xsl:template match="text() | comment() | processing-instruction()"> 
     <xsl:copy /> 
    </xsl:template> 
</xsl:stylesheet> 
+0

. 감사. – Toya

+0

질문이 수정되었습니다. – Toya

답변

0

복사 모든 노드와 다음 템플릿에서 경기를 피하는 노드, XSL ( 편집) 아래 참조 :

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">  
    <xsl:output method="xml" encoding="utf-8" indent="no" omit-xml-declaration="yes"/> 
    <!--copy all nodes--> 
    <xsl:template match="@*|node()">    
     <xsl:copy>     
      <xsl:apply-templates select="@*|node()" />   
     </xsl:copy>   
    </xsl:template> 
    <!--preventing spaces between nodes--> 
    <xsl:template match="text()"> 
     <xsl:value-of select="normalize-space()" /> 
    </xsl:template>  
    <!--match all elements which contain null for DELETE with doing nothing in template-->  
    <xsl:template match="/test/Value[@Action='DELETE']/*[contains(name(), 'null')]" /> 

</xsl:stylesheet> 

결과 (편집) :

<test xmlns:n0="http://mynamespace"> 
    <Value Action="DELETE"> 
     <space/> 
    </Value> 
    <Value Action="UPDATE"> 
     <space/> 
     <null/> 
     <null2/> 
    </Value> 
</test> 
+0

또한 노드 사이의 공백을 제거하려면''를 고려하십시오. – Parfait

+0

노드 이름 "null"과 "null2"에만 해당합니까? 그 작업을 가진 노드에 대해 null 값을 제거하고 싶습니다. – Toya

+0

@ 토야 XSL 코드를 편집했습니다. 지금은 동적입니다. 이름이 "null"인 모든 요소를 ​​제거합니다 (예 : "tttnull", "null2"또는 "null"과 같은 요소를 제거합니다). 또한 노드 사이에 공백을 방지하는 기능이 추가되었습니다. –

1

당신이 필요합니다

  1. 의 정체성 서식 모든 입력을 복사합니다.

  2. 다음 두 조건을 만족 각 노드와 일치하는 템플릿 :

    • 그것은 속성 삭제 설정 노드 액션로 포함된다
    • 그 이름 널 포함 ,

    suc h 노드.

    이것은 각 노드 이름에 대한 개별 템플릿보다 더 일반적이고 간결한 용액 이다 (, null2, ...).

  3. 선택적으로, 줄 바꿈 문자가 포함 된 공백 전용 텍스트 노드를 "차단"템플릿. 그 이유는 태그 사이에 개행 텍스트 노드가 개이지만 '통과'합니다. 공백은 space 태그 내에 포함됩니다.

그래서 전체 스크립트는 다음과 같이 할 수 있습니다 : 내 질문을 업데이트 한

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

    <xsl:template match="Value[@Action = 'DELETE']/*[contains(name(), 'null')]"/> 

    <xsl:template match="text()[not(normalize-space())][contains(.,'&#xA;')]"/> 

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

이것은 나를 위해 작동하지 않았다. – Toya

+0

@Valdi_Bo 코드를 제거 할 노드가 "null"로 시작하는 경우에만 유용합니다. 값이 일 경우 작동하지 않습니다. 안전 방법은 포함 된 것을 사용하는 것입니다. 제 수정 된 예를 참조하십시오. –

+0

예제 태그는 ** start **와 * null *이라는 이름으로 만 제공되었습니다. ** ** null *을 포함하는 모든 태그를 제거하는 작업 인 경우 두 번째 술어는 * starts * with * 대신 * contains * function을 포함해야합니다 (스크립트에서 방금 변경 한대로). –