2017-10-20 2 views
0

XSLT를 사용하여 HTML을 만드는 XML 파일 형식에 문제가 있습니다. 일반적으로 XML 요소에 포함 된 각 속성의 값을 순차적으로 검색하려고합니다. Currentlz이 코드는 XSLT에 하드 코드되어 있습니다. XML 파일이 변경되면 XSLT가 작동하지 않습니다. 요소의 첫 번째 속성 값을 검색하기 위해 <xsl:value-of select="@(name(@*[1]))" />과 같은 것을 사용하려고 시도했지만 작동하지 않습니다.XML 파일에서 XSLT 속성 값을 순차적으로 검색합니다.

어떻게 수행하나요?

미리 감사드립니다. @TimC 내가하지 않는 대답으로, 확인 :

<testsuites disabled="0" errors="0" failures="1" passes="16" skipped="0"  tests="17" time="1"> 
    <testsuite disabled="0" id="0" name="Bok" time="1" tests="4"> 
     <testcase classname="XYZ" name="description" Plate="blah" Distance="A" Side="L" Angle="15" failure="PASSED"> 
      <system-out/> 
      <system-err/> 
     </testcase> 
     <testcase classname="XYZ" name="description" Plate="blah" Distance="A" Side="L" Angle="60" failure="PASSED"> 
      <system-out/> 
      <system-err/> 
     </testcase> 
     <testcase classname="XYZ" name="description" Plate="blah" Distance="A" Side="L" Angle="30" failure="PASSED"> 
      <system-out/> 
      <system-err/> 
     </testcase> 
     <testcase classname="XYZ" name="description" Plate="blah" Distance="A" Side="L" Angle="60" failure="PASSED"> 
      <system-out/> 
      <system-err/> 
     </testcase> 
    </testsuite> 
    ... and so one 

편집 : 여기

<xsl:for-each select="testsuites/testsuite/testcase"> 
    <xsl:if test="@failure='PASSED'"> 
     <tr style="color:green;font-weight:bold"> 
      <td style="text-align:center"> 
       <xsl:value-of select="@classname" /> 
      </td> 
      <td style="text-align:center"> 
       <xsl:value-of select="@name" /> 
      </td> 
      <td style="text-align:center"> 
       <xsl:value-of select="@Plate" /> 
      </td> 
      <td style="text-align:center"> 
       <xsl:value-of select="@Distance" /> 
      </td> 
      <td style="text-align:center"> 
       <xsl:value-of select="@Side" /> 
      </td> 
      <td style="text-align:center"> 
       <xsl:value-of select="@Angle" /> 
      </td> 
      <td style="text-align:center"> 
       <xsl:value-of select="@failure" /> 
      </td> 
      <td style="text-align:center"> 
       <xsl:value-of select="failure/@message" /> 
      </td> 
     </tr> 
    </xsl:if> 
    ... and so one 

내 XML 파일의 일부입니다 : 여기

은 순간처럼 보이는 방법이다 @(name(@*[1]))에 대괄호와 이름이 필요하며 나에게 좋습니다. XML 속성은-않은 주문하고, 주석에서 언급 한 바와 같이

<xsl:for-each select="$var=1 to 7"> 
    <td style="text-align:center"> 
     <xsl:value-of select="@*[$var]" /> 
    </td> 
</xsl:for-each> 
+0

샘플 오류는 첫 번째 속성이 아니며 실제로는 실패가 아니라 실패입니다. – derloopkat

+0

@derloopkat 어쨌든 속성의 순서가 지정되지 않았기 때문에 소스 코드의 순서는 아무런 의미가 없습니다. – Tomalak

+0

글쎄, 첫 번째 속성 값을 원한다고 했잖아. – derloopkat

답변

1

내가 HTML을 만들기 위해 XSLT를 사용하여 형식의 XML 파일에 문제가있어했습니다 '를보십시오. 일반적으로 XML 요소에 포함 된 각 속성 의 값을 순차적으로 검색하려고합니다. Currentlz는 XSLT에 하드 코드되어 있으며 은 XML 파일이 변경되면 XSLT가 작동하지 않는다는 것을 인식합니다.

입력 XML의 형식이 실제로 걱정하고 현재 고려해야 할 사항입니까? 생각 해봐. 어쨌든 기존의 변환이 입력 XML 형식의 변경에서 올바르게 수행되는지 여부는 변환의 작업이 무엇이고 어떤 변화가 발생하는지에 따라 다릅니다.

특정 작업 순서를 특정 순서로 제시하는 것이라면 그 작업이 훌륭하게 수행되는 것처럼 보입니다. 특히 입력 된 문서에 나타나는 순서에 관계없이 선택한 필드를 일관된 순서로 표시하여 실제로 존재하지 않는 속성에 대해 빈 셀을 표시합니다. 산출물이 사람의 소비를 위해 의도 된 것이라면, 그 모든 것은 아마 이 좋은 일일 것입니다. I

는 요소의 첫 번째 속성 값을 검색 할 같은 것을 사용했지만, 그것은 작동하지 않습니다.

좋아요. @TimC이 대답 할 때 @ (name (@ * [1])에 대괄호와 이름이 필요하지 않습니다. 그리고 괜찮습니다.

이제 문제는 정말이 다음 절차 프로그래머처럼 생각을 멈출 수행 할 경우의 7

번호를 말할 수 있도록 1 반복하는 요소가 될 것입니다 루프를 만드는 방법입니다. XSLT에는 루프가 없습니다. 그 자체는입니다. 운영 모드에는 하나 이상의 노드를 선택한 다음 템플릿을 인스턴스화하기위한 컨텍스트로 각 노드를 차례로 사용합니다. 정렬 지시문이 없으면 문서 순서로 노드를 처리합니다. 당신은 그것이 필요로하는 것보다 훨씬 더 힘들게하려고 노력하고 있습니다.

<xsl:for-each select="@*"> 
    <td style="text-align:center"> 
     <xsl:value-of select="." /> 
    </td> 
</xsl:for-each> 

당신이 첫 번째 7을 처리 할 경우에 관계없이 예를 들면 다음과 같습니다

, 각 < 테스트 케이스> 컨텍스트 노드의 모든 속성을 처리 할 경우, 당신이 필요로하는 모든이 같은 것입니다 의 얼마나 많은 다음 선택에을 지정

<xsl:for-each select="@*[position() < 8]"> 
    <td style="text-align:center"> 
     <xsl:value-of select="." /> 
    </td> 
</xsl:for-each> 

하는 반면에, 당신은 당신이 방출되도록하려는 경우 정확히 7 < TD> 많은 속성이 있는지 여부를 각 테스트 케이스에 대 한 요소 안 그러면 안돼.

<td style="text-align:center"> 
    <xsl:value-of select="@*[1]" /> 
</td> 
<td style="text-align:center"> 
    <xsl:value-of select="@*[2]" /> 
</td> 
<!-- ... --> 

그렇지 않으면 당신은 반복이 같은 아마 뭔가를 수행하는 템플릿을 작성할 필요가 : 원래 XSL의 라인을 따라 뭔가에 돌아 ...

<xsl:call-template name="iterate-testcase-attributes"> 
    <xsl:with-param name="up-to" select="7"/> 
</xsl:call-template> 

<xsl:template name="iterate-testcase-attributes"> 
    <xsl:param name="current" select="1"/> 
    <xsl:param name="up-to" select="1"/><!-- the select value is only a default --> 
    <td style="text-align:center"> 
    <!-- will produce nothing if the context node has no such attribute --> 
    <xsl:value-of select="@*[position() = $current]" /> 
    </td> 
    <xsl:if test="$current < $up-to"> 
    <xsl:call-template name="iterate-testcase-attributes"> 
     <xsl:with-param name="current" select="$current + 1"/> 
     <xsl:with-param name="up-to" select="$up-to"/> 
    </xsl:call-template> 
    </xsl:if> 
</xsl:template> 
+0

조언을 해주셔서 감사합니다. 나는 그들을 자세히 관찰해야합니다. 일반적으로 나는 XSLT 코딩에 익숙하지 않습니다. 그래서 나는 질문을한다.) – asdator1213

+0

내 의도는 누군가가 XML에 새로운 속성을 적게 또는 더 추가 한 후에 많은 변화가 필요하지 않은 XSLT를 만드는 것이었다. 어쨌든 다시 도움을 주셔서 감사합니다. – asdator1213

+0

@ asdator1213, 나는 적어도 자신에게, (1) 현재 예상되는 속성 중 하나가 제공되지 않았거나 (2) 추가 속성이 제공되는 경우 생성하려는 출력을 분명히해야한다고 생각합니다. , 또는 (3) 속성은 당신이 보던 것과 다른 순서로 표시됩니다. 이것이 없으면 후보 스타일 시트를 평가할 방법이 없습니다. –

0

:

이제 문제는 내가 이런 걸 의미의 7을 말할 수 있도록 1에서 반복하는 요소가 될 것입니다 루프를 만드는 방법입니다 . 당신은 모두가 순서에 관계없이 속성을 얻으려면 원하는 경우, 당신은 ...

<xsl:for-each select="@*"> 
    <td style="text-align:center"> 
    <xsl:value-of select="." /> 
    </td> 
</xsl:for-each> 

을이 작업을 수행하지만, 여러 testcase 요소 수, 각 행의 속성이 동일한 순서로 보장은 없습니다. 그러나 XSLT를 가능한 한 포괄적으로 만들고 싶다면 첫 번째 행을 기준으로 순서를 정할 수 있습니다.

이 XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:template match="/"> 
    <table border="1"> 
     <xsl:variable name="attrs" select="testsuites/testsuite[1]/testcase[1]/@*" /> 
     <tr> 
     <xsl:for-each select="$attrs"> 
      <th> 
      <xsl:value-of select="local-name()" /> 
      </th> 
     </xsl:for-each> 
     </tr> 
     <xsl:for-each select="testsuites/testsuite/testcase[@failure='PASSED']"> 
     <xsl:variable name="currentCase" select="." />  
     <tr style="color:green;font-weight:bold"> 
      <xsl:for-each select="$attrs"> 
      <xsl:variable name="currentAttr" select="local-name()" />  
      <td style="text-align:center"> 
       <xsl:value-of select="$currentCase/@*[local-name() = $currentAttr]" /> 
      </td> 
      </xsl:for-each> 
     </tr> 
     </xsl:for-each> 
    </table> 
    </xsl:template> 
</xsl:stylesheet> 
+0

답장을 보내 주셔서 감사합니다;) – asdator1213

관련 문제