문제

다음 XML이 주어지면:

<current>
  <login_name>jd</login_name>
</current>
<people>
  <person>
    <first>John</first>
    <last>Doe</last>
    <login_name>jd</login_name>
  </preson>
  <person>
    <first>Pierre</first>
    <last>Spring</last>
    <login_name>ps</login_name>
  </preson>
</people>

현재/로그인 일치자 내에서 "John Doe"를 어떻게 얻을 수 있나요?

나는 다음을 시도했다:

<xsl:template match="current/login_name">
  <xsl:value-of select="../people/first[login_name = .]"/>
  <xsl:text> </xsl:text>
  <xsl:value-of select="../people/last[login_name = .]"/>
</xsl:template>
도움이 되었습니까?

해결책

사람들을 색인화하는 키를 정의하겠습니다.

<xsl:key name="people" match="person" use="login_name" />

여기서 키를 사용하면 코드가 깔끔하게 유지되지만, 자주 검색해야 하는 경우 효율성을 높이는 데 도움이 될 수도 있습니다. <person> 요소를 기반으로 한 요소 <login_name> 어린이.

주어진 형식의 이름을 반환하는 템플릿이 있습니다. <person>:

<xsl:template match="person" mode="name">
  <xsl:value-of select="concat(first, ' ', last)" />
</xsl:template>

그런 다음 나는 다음을 수행합니다.

<xsl:template match="current/login_name">
  <xsl:apply-templates select="key('people', .)" mode="name" />
</xsl:template>

다른 팁

당신이 원하는 current() 기능

<xsl:template match="current/login_name">
  <xsl:value-of select="../../people/person[login_name = current()]/first"/>
  <xsl:text> </xsl:text>
  <xsl:value-of select="../../people/person[login_name = current()]/last"/>
</xsl:template>

또는 좀 더 깔끔합니다.

<xsl:template match="current/login_name">
  <xsl:for-each select="../../people/person[login_name = current()]">
    <xsl:value-of select="first"/>
    <xsl:text> </xsl:text>
    <xsl:value-of select="last"/>
  </xsl:for-each>
</xsl:template>

여러 사용자에게 액세스해야 하는 경우 제니티의 <xsl:key /> 접근하다 이상적입니다.

이에 대한 나의 대안은 다음과 같습니다.

<xsl:template match="current/login_name">
    <xsl:variable name="person" select="//people/person[login_name = .]" />
    <xsl:value-of select="concat($person/first, ' ', $person/last)" />
</xsl:template>

우리는 선택한 것을 할당합니다 <person> 노드를 변수에 추가한 다음 concat() 이름/성을 출력하는 함수입니다.

예제 XML에도 오류가 있습니다.그만큼 <person> 노드가 다음으로 잘못 끝납니다. </preson> (오식)

XML 문서의 전체 구조(루트 노드 등)를 알고 있다면 더 나은 솔루션이 제공될 수 있습니다.

내 생각에 그가 실제로 원한 것은 사람 노드의 일치가 아니라 "현재" 노드의 일치에서 교체하는 것이었습니다.

<xsl:variable name="login" select="//current/login_name/text()"/>

<xsl:template match="current/login_name">
<xsl:value-of select='concat(../../people/person[login_name=$login]/first," ", ../../people/person[login_name=$login]/last)'/>

</xsl:template>

내 생각을 스택에 추가하기 위해

<xsl:template match="login_name[parent::current]">
 <xsl:variable name="login" select="text()"/>
 <xsl:value-of select='concat(ancestor::people/child::person[login_name=$login]/child::first/text()," ",ancestor::people/child::person[login_name=$login]/child::last/text())'/>
</xsl:template>

나는 항상 내 XPath에서 더 장황하지만 더 명확한 IMHO에서 축을 명시적으로 사용하는 것을 선호합니다.

XML 문서의 나머지 부분이 어떻게 보이는지에 따라(단순한 조각이라고 가정) "ancestor::people"에 대한 참조를 제한해야 할 수도 있습니다. 예를 들어 "ancestor::people[1]"을 사용하여 첫 번째 사람으로 제한해야 할 수도 있습니다. 선조.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top