2009-07-13 3 views
2

나는 Filemaker를 언급하면서 누구도 잃지 않기를 바란다. 나는 그것을 SSIS에서 사용할 수있는 것으로 XML 내보내기로 바꾸려고합니다. FM의 네이티브 XML 내보내기에는 동일한 XML 파일의 별도 섹션에 필드 이름과 데이터가 있습니다. 여기에 내가해야 할 일, 현재 내가 한 일, 참조 용으로 밑에있는 원래 FM 내보내기가 나와 있습니다. 나는 오늘 아침 전에 XML 번역본을 보지 못했다. 그래서 나와 함께 감당해라. D. 필요한만큼 더 많은 정보를 게시 할 수 있습니다.XSLT 질문입니다. 원본 XML이 개별 섹션에 필드 태그가있는 경우 필드 태그와 데이터를 쌍으로 만드는 방법은 무엇입니까?

<!-- What we actually want example --> 
<?xml version="1.0" encoding="UTF-8"?> 

<PRODUCTRECS> 
<PRODUCT> 
    <name>Dr. Zim</name> 
    <address>1234 Internet Way</address> 
    <city/><state/><zip/> 
</PRODUCT> 
... 
</PRODUCTRECS> 

상단에있는 필드 이름을 읽고 우리가 그것을 번역 할 때 실제 데이터 주위에 필드 이름을 넣어 XSLT있는 방법이 있습니까? 현재, 난 그냥 (작동하지만 매우 의존하고 지저분하다)과 같이 IF 문에 위치 골라 :

<!-- Current nightmare code, check for each individually and print it out --> 
<xsl:template match="fmp:FMPXMLRESULT"> 
<PRODUCTRECS> 
<xsl:for-each select="fmp:RESULTSET/fmp:ROW"> 
    <PRODUCT> 
<xsl:for-each select="fmp:COL"> 
<xsl:if test="position()=1"> 
    <name><xsl:value-of select="fmp:DATA"/></name> 
</xsl:if> 
... 
</xsl:for-each> 
    </PRODUCT> 
</xsl:for-each> 
</PRODUCTRECS> 
</xsl:template> 

이 인을 기본적으로 파일 메이커의 출력 무엇 :

<?xml version="1.0" encoding="UTF-8" ?> 
<FMPXMLRESULT xmlns="http://www.filemaker.com/fmpxmlresult"> 
<ERRORCODE>0</ERRORCODE> 
<PRODUCT BUILD="01-01-2009" NAME="FileMaker Pro" VERSION="10.0v3"/> 
<DATABASE DATEFORMAT="M/d/yyyy" LAYOUT="" NAME="filename.fp7" RECORDS="10" TIMEFORMAT="h:mm:ss a"/> 
<METADATA> 
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="name" TYPE="TEXT"/> 
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="address" TYPE="TEXT"/> 
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="city" TYPE="TEXT"/> 
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="state" TYPE="TEXT"/> 
    <FIELD EMPTYOK="YES" MAXREPEAT="1" NAME="zip" TYPE="TEXT"/> 
</METADATA> 
<RESULTSET FOUND="10"> 
<ROW MODID="0" RECORDID="1"> 
    <COL><DATA>Dr. Zim</DATA></COL> 
    <COL><DATA>1234 Internet Way</DATA></COL> 
    <COL><DATA></DATA></COL> 
    <COL><DATA></DATA></COL> 
    <COL><DATA></DATA></COL> 
    ... 
</ROW> 
... 
</RESULTSET> 
</FMPXMLRESULT> 

은 기대 거기 전문가 XSLTers. :) 내가 가진 또 다른 질문은 원본이 $ 9.99의 통화로 XML에 Text (00009.99000000)로 저장 될 때 숫자 가격을 형식화하는 방법 이었지만이 작업을 할 수있었습니다.

+0

re : 귀하의 서식 질문 - http://www.w3schools.com/XSL/func_formatnumber.asp – annakata

답변

6

이 문제를 해결하는 한 가지 우아한 방법은 이것이다 :

내 시스템에서 출력
<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:fmp="http://www.filemaker.com/fmpxmlresult" 
    exclude-result-prefixes="fmp" 
> 

    <!-- the key indexes the METADATA fields by their position --> 
    <xsl:key 
    name="kMetaData" 
    match="fmp:METADATA/fmp:FIELD" 
    use="count(preceding-sibling::fmp:FIELD) + 1" 
    /> 

    <!-- separate templates increase readability --> 
    <xsl:template match="/fmp:FMPXMLRESULT"> 
    <PRODUCTRECS> 
     <xsl:apply-templates select="fmp:RESULTSET/fmp:ROW" /> 
    </PRODUCTRECS> 
    </xsl:template> 

    <xsl:template match="fmp:ROW"> 
    <PRODUCT> 
     <xsl:apply-templates select="fmp:COL" /> 
    </PRODUCT> 
    </xsl:template> 

    <xsl:template match="fmp:COL"> 
    <!-- column name lookup is high-speed because of the key --> 
    <xsl:element name="{string(key('kMetaData', position())/@NAME)}"> 
     <xsl:value-of select="fmp:DATA" /> 
    </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

그러나

<PRODUCTRECS> 
    <PRODUCT> 
    <name>Dr. Zim</name> 
    <address>1234 Internet Way</address> 
    <city></city> 
    <state></state> 
    <zip></zip> 
    </PRODUCT> 
</PRODUCTRECS> 

, XML 요소 이름은 파일 메이커 열보다 엄격한 규칙이 적용됩니다 있다는 경고 이름. 열 이름이 해당 규칙을 위반하면 위의 내용이 충돌하고 화상을 입습니다.

스타일 시트의 주목할만한 기능은 다음과 같습니다

  • <xsl:key> 노드의 빠른 검색을 위해이 -이 결과에 fmp 네임 스페이스의 선언을 방지하기 위해 더 큰 입력
  • exclude-result-prefixes을 위해 눈에 띄는이되어야
  • <xsl:element> 동적 이름을 사용하여 요소를 만들려면
  • 노드 위치를 결정하는 방법으로 preceding-sibling XPath 축을 사용합니다 (position() 기능이 작동하지 않습니다. <xsl:key> s

불명확 한 점이 있으면 물어보십시오.

기타 문제 (숫자 형식)에 대한 대답은 XSL: Formatting numbers, excluding trailing zeroes입니다.

+0

환상적입니다. 빠른 질문, 필드 이름에서 공백을 제거하는 방법은 무엇입니까? 그들의 공간은 이상한 결과를 일으킨다. –

+0

번역 (문자열 (키 ('kMetaData', 위치())/@ NAME), '', '') – Tomalak

+0

니스! 개인적으로 모든 도움과 지식에 감사드립니다. –

1

당신은 //fmp:FMPXMLRESULT/fmp:METADATA/fmp:FIELD

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" 
     xmlns:fmp="http://www.filemaker.com/fmpxmlresult" 
    > 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:template match="/fmp:FMPXMLRESULT"> 
     <PRODUCTRECS> 
      <xsl:apply-templates select="fmp:RESULTSET/fmp:ROW" /> 
     </PRODUCTRECS> 
    </xsl:template> 

    <xsl:template match="fmp:RESULTSET/fmp:ROW"> 
     <PRODUCT> 
      <xsl:apply-templates select="fmp:COL" /> 
     </PRODUCT> 
    </xsl:template> 

    <xsl:template match="fmp:COL"> 
     <xsl:variable name="currentPosition" select="position()" /> 
     <xsl:element name="{/fmp:FMPXMLRESULT/fmp:METADATA/fmp:FIELD[position() = $currentPosition]/@NAME}"> 
      <xsl:value-of select="fmp:DATA"/> 
     </xsl:element> 
    </xsl:template> 


</xsl:stylesheet> 
1

와 XPath 쿼리를 시작 루트에서 다시 이동할 수 있습니다이 가야 당신은 시작 :

또한
<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:fm="http://www.filemaker.com/fmpxmlresult"> 
    <xsl:template match="/fm:FMPXMLRESULT"> 
     <PRODUCTRECS> 
      <xsl:apply-templates select="fm:RESULTSET/fm:ROW"/> 
     </PRODUCTRECS> 
    </xsl:template> 

    <xsl:template match="fm:ROW"> 
     <PRODUCT> 
     <!-- 
      Use this if the element containing the NAME="FileMaker Pro" attribute is the one you want to use 
      for each row name. 
      <xsl:element name="{name(/fm:FMPXMLRESULT/*[@NAME='FileMaker Pro'])}">--> 
      <xsl:for-each select="fm:COL/fm:DATA"> 
       <xsl:variable name="currentPos" select="position()"/> 
       <xsl:element name="{/fm:FMPXMLRESULT/fm:METADATA/fm:FIELD[position()=$currentPos]/@NAME}"> 
        <xsl:value-of select="."/> 
       </xsl:element> 
      </xsl:for-each> 
     <!--</xsl:element>--> 
     </PRODUCT> 
    </xsl:template> 
</xsl:stylesheet> 

이의에 대한 xsl:number에서 살펴 다른 부분 또는 아마도 number() function.

관련 문제